diff -urN fbi-1.26/GNUmakefile fbi-1.26-patch/GNUmakefile
--- fbi-1.26/GNUmakefile	2003-02-05 17:53:05.000000000 +0000
+++ fbi-1.26-patch/GNUmakefile	2003-08-21 16:57:22.000000000 +0100
@@ -3,7 +3,7 @@
 include mk/Variables.mk
 
 # add our flags + libs
-CFLAGS	+= -DVERSION='"$(VERSION)"'
+CFLAGS  += $(EXTCFLAGS) -DVERSION='"$(VERSION)"'
 LDLIBS	+= -lm
 
 # build
@@ -28,6 +28,7 @@
 HAVE_LIBUNGIF	:= $(call ac_lib,DGifOpenFileName,ungif)
 HAVE_LIBPNG	:= $(call ac_lib,png_read_info,png,-lz)
 HAVE_LIBTIFF	:= $(call ac_lib,TIFFOpen,tiff)
+HAVE_LIBCURL	:= $(call ac_lib,curl_easy_init,curl)
 endef
 
 
@@ -44,19 +45,21 @@
 endif
 
 includes	= ENDIAN_H
-libraries	= PCD JPEG UNGIF PNG TIFF
+libraries	= PCD JPEG UNGIF PNG TIFF CURL
 
 PCD_LDLIBS	:= -lpcd
 JPEG_LDLIBS	:= -ljpeg
 UNGIF_LDLIBS	:= -lungif
 PNG_LDLIBS	:= -lpng -lz
 TIFF_LDLIBS	:= -ltiff
+CURL_LDLIBS	:= -lcurl
 
 PCD_OBJS	:= pcd.o
 JPEG_OBJS	:= jpeg.o
 UNGIF_OBJS	:= gif.o
 PNG_OBJS	:= png.o
 TIFF_OBJS	:= tiff.o
+CURL_OBJS	:= curl.o
 
 inc_cflags	:= $(call ac_inc_cflags,$(includes))
 lib_cflags	:= $(call ac_lib_cflags,$(libraries))
diff -urN fbi-1.26/bmp.c fbi-1.26-patch/bmp.c
--- fbi-1.26/bmp.c	2003-02-07 10:01:58.000000000 +0000
+++ fbi-1.26-patch/bmp.c	2003-08-21 16:57:22.000000000 +0100
@@ -6,6 +6,7 @@
 # include <endian.h>
 #endif
 
+#include "curl.h"
 #include "loader.h"
 
 /* ---------------------------------------------------------------------- */
@@ -58,11 +59,11 @@
 struct bmp_state {
     struct bmp_hdr  hdr;
     struct bmp_cmap cmap[256];
-    FILE *fp;
+    URL_FILE *fp;
 };
 
 static void*
-bmp_init(FILE *fp, char *filename, struct ida_image_info *i)
+bmp_init(URL_FILE *fp, char *filename, struct ida_image_info *i)
 {
     struct bmp_state *h;
     
@@ -70,8 +71,8 @@
     memset(h,0,sizeof(*h));
     h->fp = fp;
 
-    fseek(fp,10,SEEK_SET);
-    fread(&h->hdr,sizeof(struct bmp_hdr),1,fp);
+    url_fseek(fp,10,SEEK_SET);
+    url_fread(&h->hdr,sizeof(struct bmp_hdr),1,fp);
 
 #if BYTE_ORDER == BIG_ENDIAN
     h->hdr.foobar      = le32_to_cpu(h->hdr.foobar);
@@ -118,8 +119,8 @@
     if (h->hdr.num_colors > 256)
 	h->hdr.num_colors = 256;
     if (h->hdr.num_colors) {
-	fseek(fp,14+h->hdr.size,SEEK_SET);
-	fread(&h->cmap,sizeof(struct bmp_cmap),h->hdr.num_colors,fp);
+	url_fseek(fp,14+h->hdr.size,SEEK_SET);
+	url_fread(&h->cmap,sizeof(struct bmp_cmap),h->hdr.num_colors,fp);
     }
     
     i->width  = h->hdr.width;
@@ -141,13 +142,13 @@
     
     ll = (((h->hdr.width * h->hdr.bit_cnt + 31) & ~0x1f) >> 3);
     y  = h->hdr.height - line - 1;
-    fseek(h->fp,h->hdr.foobar + y * ll,SEEK_SET);
+    url_fseek(h->fp,h->hdr.foobar + y * ll,SEEK_SET);
 
     switch (h->hdr.bit_cnt) {
     case 1:
 	for (x = 0; x < h->hdr.width; x++) {
 	    if (0 == (x & 0x07))
-		byte = fgetc(h->fp);
+		byte = url_fgetc(h->fp);
 	    pixel = byte & (0x80 >> (x & 0x07)) ? 1 : 0;
 	    *(dst++) = h->cmap[pixel].red;
 	    *(dst++) = h->cmap[pixel].green;
@@ -159,7 +160,7 @@
 	    if (x & 1) {
 		pixel = byte & 0xf;
 	    } else {
-		byte = fgetc(h->fp);
+		byte = url_fgetc(h->fp);
 		pixel = byte >> 4;
 	    }
 	    *(dst++) = h->cmap[pixel].red;
@@ -169,7 +170,7 @@
 	break;
     case 8:
 	for (x = 0; x < h->hdr.width; x++) {
-	    pixel = fgetc(h->fp);
+	    pixel = url_fgetc(h->fp);
 	    *(dst++) = h->cmap[pixel].red;
 	    *(dst++) = h->cmap[pixel].green;
 	    *(dst++) = h->cmap[pixel].blue;
@@ -177,9 +178,9 @@
 	break;
     case 24:
 	for (x = 0; x < h->hdr.width; x++) {
-	    dst[2] = fgetc(h->fp);
-	    dst[1] = fgetc(h->fp);
-	    dst[0] = fgetc(h->fp);
+	    dst[2] = url_fgetc(h->fp);
+	    dst[1] = url_fgetc(h->fp);
+	    dst[0] = url_fgetc(h->fp);
 	    dst += 3;
 	}
 	break;
@@ -194,7 +195,7 @@
 {
     struct bmp_state *h = data;
 
-    fclose(h->fp);
+    url_fclose(h->fp);
     free(h);
 }
 
diff -urN fbi-1.26/curl.c fbi-1.26-patch/curl.c
--- fbi-1.26/curl.c	1970-01-01 01:00:00.000000000 +0100
+++ fbi-1.26-patch/curl.c	2003-08-21 16:57:22.000000000 +0100
@@ -0,0 +1,495 @@
+/*****************************************************************************
+ *
+ * This example source code introduces a c library buffered I/O interface to
+ * URL reads it supports fopen(), fread(), fgets(), feof(), fclose(),
+ * rewind(). Supported functions have identical prototypes to their normal c
+ * lib namesakes and are preceaded by url_ .
+ *
+ * Using this code you can replace your program's fopen() with url_fopen()
+ * and fread() with url_fread() and it become possible to read remote streams
+ * 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.
+ *
+ * Coyright (c)2003 Simtec Electronics
+ *
+ * Re-implemented by Vincent Sanders <vince@kyllikki.org> with extensive
+ * reference to original curl example code
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This example requires libcurl 7.9.7 or later.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <curl/curl.h>
+
+#if (LIBCURL_VERSION_NUM < 0x070907)
+#error "too old libcurl version, get the latest!"
+#endif
+
+#include "curl.h"
+
+enum fcurl_type_e { CFTYPE_NONE=0, CFTYPE_FILE=1, CFTYPE_CURL=2 };
+
+struct fcurl_data
+{
+    enum fcurl_type_e type;	/* type of handle */
+    union {
+	CURL *curl;
+	FILE *file;
+    } handle;			/* handle */
+
+    char *buffer;		/* buffer to store cached data*/
+    int buffer_len;		/* currently allocated buffers length */
+    int buffer_pos;		/* end of data in buffer*/
+    int still_running;		/* Is background url fetch still in progress */
+};
+
+
+/* we use a global one for convenience */
+CURLM *multi_handle;
+
+/* curl calls this routine to get more data */
+static size_t
+write_callback(char *buffer,
+	       size_t size,
+	       size_t nitems,
+	       void *userp)
+{
+    char *newbuff;
+    int rembuff;
+
+    URL_FILE *url = (URL_FILE *)userp;
+    size *= nitems;
+
+    rembuff=url->buffer_len - url->buffer_pos;//remaining space in buffer
+
+    if(size > rembuff)
+    {
+	//not enuf space in buffer
+	newbuff=realloc(url->buffer,url->buffer_len + (size - rembuff));
+	if(newbuff==NULL)
+	{
+	    fprintf(stderr,"callback buffer grow failed\n");
+	    size=rembuff;
+	}
+	else
+	{
+	    /* realloc suceeded increase buffer size*/
+	    url->buffer_len+=size - rembuff;
+	    url->buffer=newbuff;
+
+	    /*printf("Callback buffer grown to %d bytes\n",url->buffer_len);*/
+	}
+    }
+
+    memcpy(&url->buffer[url->buffer_pos], buffer, size);
+    url->buffer_pos += size;
+
+    /*fprintf(stderr, "callback %d size bytes\n", size);*/
+
+    return size;
+}
+
+/* use to attempt to fill the read buffer up to requested number of bytes */
+static int
+curl_fill_buffer(URL_FILE *file,int want,int waittime)
+{
+    fd_set fdread;
+    fd_set fdwrite;
+    fd_set fdexcep;
+    int maxfd;
+    struct timeval timeout;
+    int rc;
+    CURLMcode cres;
+
+    /* only attempt to fill buffer if transactions still running and buffer
+     * doesnt exceed required size already
+     */
+    if((!file->still_running) || (file->buffer_pos > want))
+	return 0;
+
+    /* attempt to fill buffer */
+    do
+    {
+	FD_ZERO(&fdread);
+	FD_ZERO(&fdwrite);
+	FD_ZERO(&fdexcep);
+
+	/* set a suitable timeout to fail on */
+	timeout.tv_sec = 60; /* 1 minute */
+	timeout.tv_usec = 0;
+
+	/* get file descriptors from the transfers */
+	cres=curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
+
+	if(cres!=CURLM_OK)
+	{
+	    printf("curl_multi_fdset failed %d\n",cres);
+	    return -1;
+	}
+
+	rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+
+	switch(rc) {
+	case -1:
+	    /* select error */
+	    break;
+
+	case 0:
+	    break;
+
+	default:
+	    /* timeout or readable/writable sockets */
+	    /* note we *could* be more efficient and not wait for
+	     * CURLM_CALL_MULTI_PERFORM to clear here and check it on re-entry
+	     * but that gets messy */
+	    while(curl_multi_perform(multi_handle, &file->still_running) ==
+		  CURLM_CALL_MULTI_PERFORM);
+
+	    break;
+	}
+    } while(file->still_running && (file->buffer_pos < want));
+    return 1;
+}
+
+/* use to remove want bytes from the front of a files buffer */
+static int
+curl_use_buffer(URL_FILE *file,int want)
+{
+    /* sort out buffer */
+    if((file->buffer_pos - want) <=0)
+    {
+	/* ditch buffer - write will recreate */
+	if(file->buffer)
+	    free(file->buffer);
+
+	file->buffer=NULL;
+	file->buffer_pos=0;
+	file->buffer_len=0;
+    }
+    else
+    {
+	/* move rest down make it available for later */
+	memmove(file->buffer,
+		&file->buffer[want],
+		(file->buffer_pos - want));
+
+	file->buffer_pos -= want;
+    }
+    return 0;
+}
+
+
+
+URL_FILE *
+url_fopen(char *url,const char *operation)
+{
+    /* this code could check for URLs or types in the 'url' and
+       basicly use the real fopen() for standard files */
+
+    URL_FILE *file;
+    (void)operation;
+
+    file = (URL_FILE *)malloc(sizeof(URL_FILE));
+    if(!file)
+	return NULL;
+
+    memset(file, 0, sizeof(URL_FILE));
+
+    if((file->handle.file=fopen(url,operation)))
+    {
+	file->type = CFTYPE_FILE; /* marked as URL */
+    }
+    else
+    {
+	file->type = CFTYPE_CURL; /* marked as URL */
+	file->handle.curl = curl_easy_init();
+
+	curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
+	curl_easy_setopt(file->handle.curl, CURLOPT_FILE, file);
+	curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, FALSE);
+	curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback);
+
+	if(!multi_handle)
+	    multi_handle = curl_multi_init();
+
+	curl_multi_add_handle(multi_handle, file->handle.curl);
+
+	/* lets start the fetch */
+	while(curl_multi_perform(multi_handle, &file->still_running) ==
+	      CURLM_CALL_MULTI_PERFORM );
+
+	if((file->buffer_pos == 0) && (!file->still_running))
+	{
+	    /* if still_running is 0 now, we should return NULL */
+
+	    /* make sure the easy handle is not in the multi handle anymore */
+	    curl_multi_remove_handle(multi_handle, file->handle.curl);
+
+	    /* cleanup */
+	    curl_easy_cleanup(file->handle.curl);
+
+	    free(file);
+
+	    file = NULL;
+	}
+    }
+    return file;
+}
+
+int
+url_fclose(URL_FILE *file)
+{
+    int ret=0;/* default is good return */
+
+    switch(file->type)
+    {
+    case CFTYPE_FILE:
+	ret=fclose(file->handle.file); /* passthrough */
+	break;
+
+    case CFTYPE_CURL:
+	/* make sure the easy handle is not in the multi handle anymore */
+	curl_multi_remove_handle(multi_handle, file->handle.curl);
+
+	/* cleanup */
+	curl_easy_cleanup(file->handle.curl);
+	break;
+
+    default: /* unknown or supported type - oh dear */
+	ret=EOF;
+	errno=EBADF;
+	break;
+
+    }
+
+    if(file->buffer)
+	free(file->buffer);/* free any allocated buffer space */
+
+    free(file);
+
+    return ret;
+}
+
+int
+url_feof(URL_FILE *file)
+{
+    int ret=0;
+
+    switch(file->type)
+    {
+    case CFTYPE_FILE:
+	ret=feof(file->handle.file);
+	break;
+
+    case CFTYPE_CURL:
+	if((file->buffer_pos == 0) && (!file->still_running))
+	    ret = 1;
+	break;
+    default: /* unknown or supported type - oh dear */
+	ret=-1;
+	errno=EBADF;
+	break;
+    }
+    return ret;
+}
+
+size_t
+url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file)
+{
+    size_t want;
+
+    switch(file->type)
+    {
+    case CFTYPE_FILE:
+	want=fread(ptr,size,nmemb,file->handle.file);
+	break;
+
+    case CFTYPE_CURL:
+	want = nmemb * size;
+
+	curl_fill_buffer(file,want,1);
+
+	/* check if theres data in the buffer - if not curl_fill_buffer()
+	 * either errored or EOF */
+	if(!file->buffer_pos)
+	    return 0;
+
+	/* ensure only available data is considered */
+	if(file->buffer_pos < want)
+	    want = file->buffer_pos;
+
+	/* xfer data to caller */
+	memcpy(ptr, file->buffer, want);
+
+	curl_use_buffer(file,want);
+
+	want = want / size;	/* number of items - nb correct op - checked
+				 * with glibc code*/
+
+	/*printf("(fread) return %d bytes %d left\n", want,file->buffer_pos);*/
+	break;
+
+    default: /* unknown or supported type - oh dear */
+	want=0;
+	errno=EBADF;
+	break;
+
+    }
+    return want;
+}
+
+char *
+url_fgets(char *ptr, int size, URL_FILE *file)
+{
+    int want = size - 1;/* always need to leave room for zero termination */
+    int loop;
+
+    switch(file->type)
+    {
+    case CFTYPE_FILE:
+	ptr = fgets(ptr,size,file->handle.file);
+	break;
+
+    case CFTYPE_CURL:
+	curl_fill_buffer(file,want,1);
+
+	/* check if theres data in the buffer - if not fill either errored or
+	 * EOF */
+	if(!file->buffer_pos)
+	    return NULL;
+
+	/* ensure only available data is considered */
+	if(file->buffer_pos < want)
+	    want = file->buffer_pos;
+
+	/*buffer contains data */
+	/* look for newline or eof */
+	for(loop=0;loop < want;loop++)
+	{
+	    if(file->buffer[loop] == '\n')
+	    {
+		want=loop+1;/* include newline */
+		break;
+	    }
+	}
+
+	/* xfer data to caller */
+	memcpy(ptr, file->buffer, want);
+	ptr[want]=0;/* allways null terminate */
+
+	curl_use_buffer(file,want);
+
+	/*printf("(fgets) return %d bytes %d left\n", want,file->buffer_pos);*/
+	break;
+
+    default: /* unknown or supported type - oh dear */
+	ptr=NULL;
+	errno=EBADF;
+	break;
+    }
+
+    return ptr;/*success */
+}
+
+void
+url_rewind(URL_FILE *file)
+{
+    char * url;
+
+    switch(file->type)
+    {
+    case CFTYPE_FILE:
+	rewind(file->handle.file); /* passthrough */
+	break;
+
+    case CFTYPE_CURL:
+	/* halt transaction */
+	curl_multi_remove_handle(multi_handle, file->handle.curl);
+	curl_multi_cleanup(multi_handle);
+
+	curl_easy_getinfo(file->handle.curl, CURLINFO_EFFECTIVE_URL, &url );
+
+	/* cleanup */
+	curl_easy_cleanup(file->handle.curl);
+
+	/* ditch buffer - write will recreate - resets stream pos*/
+	if(file->buffer)
+	    free(file->buffer);
+
+	file->buffer=NULL;
+	file->buffer_pos=0;
+	file->buffer_len=0;
+
+	file->handle.curl = curl_easy_init();
+
+	curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
+	curl_easy_setopt(file->handle.curl, CURLOPT_FILE, file);
+	curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, FALSE);
+	curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback);
+
+	multi_handle = curl_multi_init();
+
+	/* restart */
+	curl_multi_add_handle(multi_handle, file->handle.curl);
+
+	/* re-start the fetch! */
+	while(curl_multi_perform(multi_handle, &file->still_running) ==
+	      CURLM_CALL_MULTI_PERFORM );
+
+	break;
+
+    default: /* unknown or supported type - oh dear */
+	break;
+
+    }
+
+}
+
+int
+url_fgetc(URL_FILE *file)
+{
+    unsigned char retc;
+    int reti;
+    reti = url_fread(&retc, 1, 1, file);
+    if(reti!=1)
+	return reti;
+
+    return retc;
+}
+
+int
+url_fseek(URL_FILE *stream, long offset, int whence)
+{
+    errno=EBADF;
+    return -1;
+}
diff -urN fbi-1.26/curl.h fbi-1.26-patch/curl.h
--- fbi-1.26/curl.h	1970-01-01 01:00:00.000000000 +0100
+++ fbi-1.26-patch/curl.h	2003-08-21 16:57:22.000000000 +0100
@@ -0,0 +1,29 @@
+#ifdef HAVE_LIBCURL
+
+typedef struct fcurl_data URL_FILE;
+
+/* exported functions */
+URL_FILE *url_fopen(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, int size, URL_FILE *file);
+void url_rewind(URL_FILE *file);
+int url_fseek(URL_FILE *file, long offset, int whence);
+int url_fgetc(URL_FILE *file);
+
+
+#else
+
+#define URL_FILE FILE
+#define url_fopen fopen
+#define url_fclose fclose
+#define url_feof feof
+#define url_fread fread
+#define url_fgets fgets
+#define url_fseek fseek
+#define url_fgetc fgetc
+
+#define url_rewind rewind
+
+#endif
diff -urN fbi-1.26/fbi.c fbi-1.26-patch/fbi.c
--- fbi-1.26/fbi.c	2003-01-30 16:13:38.000000000 +0000
+++ fbi-1.26-patch/fbi.c	2003-08-22 02:05:11.000000000 +0100
@@ -22,6 +22,7 @@
 #include <sys/mman.h>
 #include <linux/fb.h>
 
+#include "curl.h"
 #include "loader.h"
 #include "dither.h"
 #include "fbtools.h"
@@ -62,8 +63,23 @@
 int             left, top;
 
 /* file list */
-char            **files;
-int             fileanz, filenr;
+
+struct fileent_s
+{
+    struct fileent_s* next;
+    char * filename;
+};
+
+typedef struct fileent_s fileent_t;
+
+fileent_t* files;
+fileent_t* filenr;
+
+
+int             fileanz; /* number of files */
+
+
+
 
 char                       *fbdev = NULL;
 char                       *mode  = NULL;
@@ -89,6 +105,7 @@
     {"resolution", required_argument, NULL, 'r'},  /* select resolution */
     {"random",     no_argument,       NULL, 'u'},  /* randomize images */
     {"font",       required_argument, NULL, 'f'},  /* font */
+    {"input-file", required_argument, NULL, 'i'},  /* input files */
     {"autozoom",   no_argument,       NULL, 'a'},
     {"edit",       no_argument,       NULL, 'e'},  /* enable editing */
     {0,0,0,0}
@@ -139,6 +156,8 @@
 	    "    --font       [-f] fn   Use font fn (either console psf file or\n"
 	    "                           X11 font spec if a font server is available\n"
 	    "    --autozoom   [-a]      Automagically pick useful zoom factor.\n"
+	    "    --input-file [-i] file Read URLs from file, in which case no URLs\n"
+	    "                           need to be on the command line.\n"
 	    "    --edit       [-e]      enable editing commands (see man page).\n"
 	    "\n"
 	    "Large images can be scrolled using the cursor keys.  Zoom in/out\n"
@@ -164,14 +183,17 @@
 	f = fs_open(font ? font : x11_font);
 #endif
     if (NULL == f) {
-	fprintf(stderr,"no font available\n");
-	exit(1);
+	fprintf(stderr,"no font available - no text\n");
+	/*	exit(1);*/
     }
 }
 
 static void
 text_out(int x, int y, char *str)
 {
+    if(f == NULL)
+	return;
+
     y *= f->height;
     y -= f->fontHeader.max_bounds.descent;
     x *= f->width;
@@ -194,7 +216,7 @@
 
 static inline void fb_clear_line(void)
 {
-    if (visible)
+    if (visible && (f != NULL))
 	fb_memset(fb_mem,0,fb_fix.line_length * f->height);
 }
 
@@ -207,10 +229,10 @@
 tty_raw(void)
 {
     struct termios tattr;
-    
+
     fcntl(0,F_GETFL,&saved_fl);
     tcgetattr (0, &saved_attributes);
-    
+
     fcntl(0,F_SETFL,O_NONBLOCK);
     memcpy(&tattr,&saved_attributes,sizeof(struct termios));
     tattr.c_lflag &= ~(ICANON|ECHO);
@@ -243,7 +265,7 @@
 	ioctl(fd,FBIOPAN_DISPLAY,&fb_var);
 	fb_clear_screen();
 	if (is_busy)
-	    text_out(0,0,"still busy, please wait ...");		
+	    text_out(0,0,"still busy, please wait ...");
 	break;
     default:
 	break;
@@ -262,10 +284,13 @@
     struct ida_loader *loader;
     struct ida_image_info info;
     char blk[512];
-    FILE *fp;
+    URL_FILE *fp;
     void *data;
     int l,y;
-    
+
+    fprintf(stderr,"reading image >%s<\n",filename);
+
+
     if (image) {
 	free(image);
 	image = NULL;
@@ -273,13 +298,13 @@
     new_image = 1;
 
     /* open file */
-    if (NULL == (fp = fopen(filename, "r"))) {
+    if (NULL == (fp = url_fopen(filename, "r"))) {
 	fprintf(stderr,"open %s: %s\n",filename,strerror(errno));
 	return NULL;
     }
     memset(blk,0,sizeof(blk));
-    fread(blk,1,sizeof(blk),fp);
-    rewind(fp);
+    url_fread(blk,1,sizeof(blk),fp);
+    url_rewind(fp);
 
     /* pick loader */
     for (l = 0;; l++) {
@@ -433,12 +458,12 @@
     unsigned char *ptr;
     static char *image = NULL;
     int shift = zoom + 16;
-    
+
     if (image) {
 	free(image);
 	image = NULL;
     }
-    
+
     *owidth  = iwidth;
     *oheight = iheight;
     if (zoom < 0) {
@@ -465,41 +490,70 @@
 }
 
 /* ---------------------------------------------------------------------- */
+unsigned char
+top_n_bits( int n )
+{
+  if( n > 7 ) return ~0;
+  if( n < 1 ) return 0;
+  return (~0) << (8-n);
+}
 
 static void
 lut_init(int depth)
 {
-    register int    i;
+    int c=8;
+
+    unsigned int    i;/* index */
+    unsigned char    rm,gm,bm;/* reg green blue masks */
+    unsigned char    rs,gs,bs;/* reg green blue shifts */
+
+    //lut_XX[i] = ((i * ((2**(fb_var.XX_length+1))-1))/255) <<fb_var.XX_offset
+
+    rm= top_n_bits(fb_var.red.length);
+    gm= top_n_bits(fb_var.green.length);
+    bm= top_n_bits(fb_var.blue.length);
+
+    rs=(c - fb_var.red.length);
+    gs=(c - fb_var.green.length);
+    bs=(c - fb_var.blue.length);
+
+    /*
+      fprintf(stderr,
+      "depth %d\n r off %d len %d mask %x shift %d\n",
+      depth,
+      fb_var.red.offset,
+      fb_var.red.length,
+      rm,
+      rs);
+
+      fprintf(stderr,
+      "g off %d len %d mask %x shift %d\n",
+      fb_var.green.offset,
+      fb_var.green.length,
+      gm,
+      gs);
+
+      fprintf(stderr,
+      "b off %d len %d mask %x shift %d\n",
+      fb_var.blue.offset,
+      fb_var.blue.length,
+      bm,
+      bs);
+    */
 
     /* init Lookup tables */
-    switch (depth) {
-    case 15:
-	for (i = 0; i < 256; i++) {
-	   lut_red[i]   = (i & 0xf8) << 7;	/* bits -rrrrr-- -------- */
-	   lut_green[i] = (i & 0xf8) << 2;	/* bits------gg ggg----- */
-	   lut_blue[i]  = (i & 0xf8) >> 3;	/* bits-------- ---bbbbb */
-	}
-	break;
-    case 16:
-	for (i = 0; i < 256; i++) {
-	   lut_red[i]   = (i & 0xf8) << 8;	/* bits rrrrr--- -------- */
-	   lut_green[i] = (i & 0xfc) << 3;	/* bits -----ggg ggg----- */
-	   lut_blue[i]  = (i & 0xf8) >> 3;	/* bits -------- ---bbbbb */
-	}
-	break;
-    case 24:
 	for (i = 0; i < 256; i++) {
-	   lut_red[i]   = i << 16;	/* byte -r-- */
-	   lut_green[i] = i << 8;	/* byte --g- */
-	   lut_blue[i]  = i;		/* byte ---b */
-	}
-	break;
+	lut_red[i]   = ((i & rm)>>rs) << fb_var.red.offset;
+	lut_green[i] = ((i & gm)>>gs) << fb_var.green.offset;
+	lut_blue[i]  = ((i & bm)>>bs) << fb_var.blue.offset;
+	/*fprintf(stderr,"i %d %x/%x/%x\n",i,lut_red[i],lut_green[i],lut_blue[i]);*/
+
     }
 }
 
 static unsigned short calc_gamma(int n, int max)
 {
-    int ret =65535.0 * pow((float)n/(max), 1 / fbgamma); 
+    int ret =65535.0 * pow((float)n/(max), 1 / fbgamma);
     if (ret > 65535) ret = 65535;
     if (ret <     0) ret =     0;
     return ret;
@@ -509,7 +563,7 @@
 linear_palette(int bit)
 {
     int i, size = 256 >> (8 - bit);
-    
+
     for (i = 0; i < size; i++)
         red[i] = green[i] = blue[i] = calc_gamma(i,size);
 }
@@ -572,7 +626,7 @@
 
     if (NULL == image)
 	return KEY_SPACE; /* skip */
-    
+
     if (new_image) {
 	/* start with centered image, if larger than screen */
 	if (width > fb_var.xres)
@@ -711,6 +765,175 @@
 
 /* ---------------------------------------------------------------------- */
 
+struct fileent_s*
+del_fileent(struct fileent_s* curent)
+{
+    /*
+    if (filenr < fileanz-1)
+	memmove(files+filenr,files+filenr+1,
+		(fileanz-1 - filenr) * sizeof(char*));
+    else {
+	 deleted last one
+	fb_clear_mem();
+	tty_restore();
+	fb_cleanup();
+	exit(0);
+    }
+    */
+    fileanz--;
+    return curent;
+
+}
+
+int
+link_ent(struct fileent_s* prevent,struct fileent_s* newent)
+{
+    if(prevent)
+    {
+	newent->next=prevent->next;
+	prevent->next=newent;
+    }
+    else
+    {
+	newent->next=NULL;
+    }
+}
+
+
+struct fileent_s*
+add_fileent(struct fileent_s* prevent,const char* filen)
+{
+    struct fileent_s* newent;
+    newent=malloc(sizeof(struct fileent_s));
+    if(newent)
+    {
+	newent->filename=strdup(filen);
+	link_ent(prevent,newent);
+	fileanz++;
+	/*fprintf(stderr,"adding file >%s< at %p fileanz is %d\n",newent->filename,newent,fileanz);*/
+
+    }
+    return newent;
+}
+
+
+int
+add_cmdln_files(char ** filenames,int filec)
+{
+    struct fileent_s* curent = files;
+    int loop;
+
+    for(loop=0;loop<filec;loop++)
+    {
+	if(curent)
+	    curent = add_fileent(curent,filenames[loop]);
+	else
+	    files = curent = add_fileent(curent,filenames[loop]);
+    }
+}
+
+int
+add_uri_files(char * filename)
+{
+    URL_FILE * infile;
+    char line[1024];
+    struct fileent_s* curent = files;
+
+    infile=url_fopen(filename,"r");
+    if(infile)
+    {
+	while(url_fgets(line,1024,infile))
+	{
+	    curent = add_fileent(curent,line);
+	    if(!files)
+		files=curent;
+
+	}
+	url_fclose(infile);
+    }
+    else
+    {
+	fprintf(stderr,"Unable to open file: %s\n",filename );
+    }
+
+    return 0;
+
+}
+
+int log2(unsigned long l);
+
+
+int
+log2(unsigned long l)
+{
+    int r=0;
+    if (l & 0xFFFF0000ul) r+=16,l>>=16;
+    if (l & 0xFF00ul) r+=8,l>>=8;
+    if (l & 0xF0ul) r+=4,l>>=4;
+    if (l & 0xCul) r+=2,l>>=2;
+    if (l & 0x2ul) r+=1,l>>=1;
+    if (l & 0x1ul) r+=1,l>>=1;
+    return r;
+}
+
+int shuffle_files(void);
+
+int shuffle_files(void)
+{
+    int             rand_one, rand_two;
+    char            *rand_temp;
+    int             count = log2(fileanz);/* log2(n) riffle shuffle */
+    int loop;
+    struct fileent_s* one,* one_cur;
+    struct fileent_s* two,* two_cur;
+    struct fileent_s* cur,* next;
+
+
+    /* Seed random number gen.  (sic) */
+    srand((unsigned)time(NULL ) );
+
+    /* Shuffle the order of the images - uses a riffle shuffle*/
+
+    for(loop = 0; loop < count; loop++ )
+    {
+	one = NULL;
+	two = NULL;
+	one_cur = NULL;
+	two_cur = NULL;
+	cur = files;
+	if(cur)
+	    next = files->next;
+
+	while(cur)
+	{
+	    if(rand() > (RAND_MAX/2))
+	    {
+		/* link to list 2*/
+		one_cur=link_ent(one_cur,cur);
+		if(!one)
+		    one=one_cur;
+	    }
+	    else
+	    {
+		/* link to list 1*/
+		two_cur=link_ent(two_cur,cur);
+		if(!two)
+		    two=two_cur;
+	    }
+	    cur=next;
+	    if(cur)
+		next=cur->next;
+	}
+	one_cur=link_ent(one_cur,two);
+	files=one;/* files = one + two */
+    }
+    return 0;
+
+}
+
+
+/* ---------------------------------------------------------------------- */
+
 int
 main(int argc, char *argv[])
 {
@@ -723,9 +946,6 @@
     unsigned char  *iimage = NULL,*image = NULL;
     int             c, rc, zoom = 0, autozoom = 0, editable = 0, once = 0;
     int             need_read, need_refresh;
-    int             rand_one, rand_two;
-    char            *rand_temp;
-    int             i;
 
     char            *basename = NULL, *line;
     char            linebuffer[128];
@@ -737,8 +957,10 @@
     if (NULL != (line = getenv("FBFONT")))
 	fontname = line;
 
+    files=NULL;/* ensure file list empty */
+
     for (;;) {
-	c = getopt_long(argc, argv, "u1evahpqr:t:m:d:g:s:f:", fbi_options, &opt_index);
+	c = getopt_long(argc, argv, "u1evahpqr:t:m:d:g:s:f:i:", fbi_options, &opt_index);
 	if (c == -1)
 	    break;
 	switch (c) {
@@ -784,6 +1006,9 @@
 	case 'e':
 	    editable = 1;
 	    break;
+	case 'i':
+	     add_uri_files(optarg);
+	    break;
 	case 'V':
 	    version();
 	    exit(0);
@@ -796,27 +1021,18 @@
     }
 
     if (optind == argc) {
-	usage(argv[0]);
-	exit(1);
+	if(fileanz==0) {
+	    usage(argv[0]);
+	    exit(1);
+	}
+    } else {
+	add_cmdln_files(argv + optind,argc - optind);
     }
-    files = argv + optind;
-    fileanz = argc - optind;
-    filenr = 0;
 
-    /* Seed random number gen.  (sic) */
-    srand((unsigned)time(NULL ) );
+    filenr = files;
 
-    /* Randomize the order of the images */
-    if (randomize != -1) {
-	/* Naive implementation - could be improved. */
-	for( i = 0; i < fileanz; i++ ) {
-	    rand_one = rand() % fileanz;
-	    rand_two = rand() % fileanz;
-	    rand_temp = files[ rand_one ];
-	    files[ rand_one ] = files[ rand_two ];
-	    files[ rand_two ] = rand_temp;
-	}
-    }
+    if(randomize != -1)
+	shuffle_files();
 
     need_read = 1;
     need_refresh = 1;
@@ -827,7 +1043,7 @@
     fb_switch_init();
     signal(SIGTSTP,SIG_IGN);
     fs_init_fb(255);
-    
+
     switch (fb_var.bits_per_pixel) {
     case 8:
 	svga_dither_palette(8, 8, 4);
@@ -881,17 +1097,23 @@
     /* svga main loop */
     tty_raw();
     for (;;) {
-	if (need_read) {
+	if (need_read)
+	{
 	    need_read = 0;
 	    need_refresh = 1;
-	    if (verbose && visible) {
-		basename = strrchr(files[filenr], '/');
-		basename = basename ? basename + 1 : files[filenr];
+
+	    if (verbose && visible)
+	    {
+		basename = strrchr(filenr->filename, '/');
+		basename = basename ? basename + 1 : filenr->filename;
 		sprintf(linebuffer,"loading %s... ", basename);
 		fb_clear_line();
-		text_out(0,0,linebuffer);		
+		text_out(0,0,linebuffer);
 	    }
-	    iimage = read_image(files[filenr], &igray, &iwidth, &iheight);
+
+	    /* pull in the image */
+	    iimage = read_image(filenr->filename, &igray, &iwidth, &iheight);
+
 	    if (iimage && autozoom) {
 		width  = iwidth;
 		height = iheight;
@@ -916,7 +1138,7 @@
 	    if (NULL == image && verbose && visible) {
 		strcat(linebuffer,"FAILED ");
 		fb_clear_line();
-		text_out(0,0,linebuffer);		
+		text_out(0,0,linebuffer);
 		sleep(1);
 	    }
 	}
@@ -926,22 +1148,14 @@
 		fb_clear_screen();
 	}
 	sprintf(linebuffer,"Viewing %s (%dx%d)", basename, iwidth, iheight);
+
 	switch (rc = svga_show(image, width, height, timeout,
-			       (verbose > 1) ? linebuffer : NULL)) {
+			       (verbose > 1) ? linebuffer : NULL))
+	{
 	case KEY_DELETE:
 	    if (editable) {
-		unlink(files[filenr]);
-		if (filenr < fileanz-1)
-		    memmove(files+filenr,files+filenr+1,
-			    (fileanz-1 - filenr) * sizeof(char*));
-		else {
-		    /* deleted last one */
-		    fb_clear_mem();
-		    tty_restore();
-		    fb_cleanup();
-		    exit(0);
-		}
-		fileanz--;
+		unlink(filenr->filename);
+		filenr = del_fileent(filenr);
 		need_read = 1;
 	    } else {
 		sprintf(linebuffer,"readonly mode - sorry");
@@ -962,14 +1176,14 @@
 
 	    if (editable) {
 		if (verbose && visible) {
-		    sprintf(linebuffer,"rotate %s ... ",files[filenr]);
+		    sprintf(linebuffer,"rotate %s ... ",filenr->filename);
 		    fb_clear_line();
 		    text_out(0,0,linebuffer);
 		}
-		buf = malloc(5 * strlen(files[filenr]) + sizeof(cmd) + 8);
+		buf = malloc(5 * strlen(filenr->filename) + sizeof(cmd) + 8);
 		sprintf(buf,cmd, (rc == KEY_ROT_CW) ? 90 : 270,
-			files[filenr],files[filenr],files[filenr],
-			files[filenr],files[filenr]);
+			filenr->filename,filenr->filename,filenr->filename,
+			filenr->filename,filenr->filename);
 		system(buf);
 		free(buf);
 		need_read = 1;
@@ -982,11 +1196,13 @@
 	    break;
 	}
 	case KEY_TAGFILE:
-	    printf("%s\n",files[filenr]);
+	    printf("%s\n",filenr->filename);
 	    /* fall throuth */
 	case KEY_SPACE:
-	    if (filenr != fileanz - 1) {
-		filenr++, need_read = 1;
+	    filenr=filenr->next;
+	    if(filenr)
+	    {
+		need_read = 1;
 		break;
 	    }
 	    /* else fall */
@@ -999,24 +1215,27 @@
 	    exit(0);
 	    break;
 	case KEY_PGDN:
-	    if (filenr < fileanz - 1)
-		filenr++, need_read = 1;
+	    filenr=filenr->next;
+	    if(filenr)
+	    {
+		need_read = 1;
+	    }
 	    break;
 	case KEY_PGUP:
-	    if (filenr > 0)
-		filenr--, need_read = 1;
+	    /*	    if (filenr > 0)
+		    filenr--, need_read = 1;*/
 	    break;
 	case KEY_TIMEOUT:
 	    need_read = 1;
-	    filenr++;
-	    if (filenr == fileanz) {
+	    filenr=filenr->next;
+	    if (!filenr) {
 		if (once) {
 		    fb_clear_mem();
 		    tty_restore();
 		    fb_cleanup();
 		    exit(0);
 		} else
-		    filenr = 0;
+		    filenr = files;
 	    }
 	    break;
 	case KEY_PLUS:
@@ -1045,8 +1264,10 @@
 	    need_refresh = 1;
 	    break;
 	default:
+	    /*
 	    if (rc > 0 && rc <= fileanz)
 		filenr = rc - 1, need_read = 1;
+	    */
 	    break;
 	}
     }
diff -urN fbi-1.26/jpeg.c fbi-1.26-patch/jpeg.c
--- fbi-1.26/jpeg.c	2003-02-07 10:01:58.000000000 +0000
+++ fbi-1.26-patch/jpeg.c	2003-08-21 16:57:22.000000000 +0100
@@ -3,7 +3,9 @@
 #include <string.h>
 #include <errno.h>
 #include <jpeglib.h>
+#include <jerror.h>
 
+#include "curl.h"
 #include "loader.h"
 
 #ifdef USE_X11
@@ -17,11 +19,162 @@
 # include "viewer.h"
 #endif
 
+/* jpeg loader routines - lifted directly from jdatasrc.c */
+
+/* Expanded data source object for stdio input */
+
+typedef struct {
+  struct jpeg_source_mgr pub;	/* public fields */
+
+  URL_FILE * infile;		/* source stream */
+  JOCTET * buffer;		/* start of buffer */
+  boolean start_of_file;	/* have we gotten any data yet? */
+} my_source_mgr;
+
+typedef my_source_mgr * my_src_ptr;
+
+#define INPUT_BUF_SIZE  4096	/* choose an efficiently fread'able size */
+
+
+/*
+ * Initialize source --- called by jpeg_read_header
+ * before any data is actually read.
+ */
+
+void
+url_init_source (j_decompress_ptr cinfo)
+{
+  my_src_ptr src = (my_src_ptr) cinfo->src;
+
+  /* We reset the empty-input-file flag for each image,
+   * but we don't clear the input buffer.
+   * This is correct behavior for reading a series of images from one source.
+   */
+  src->start_of_file = TRUE;
+}
+
+
+/*
+ * Fill the input buffer --- called whenever buffer is emptied.
+ */
+
+boolean
+url_fill_input_buffer (j_decompress_ptr cinfo)
+{
+  my_src_ptr src = (my_src_ptr) cinfo->src;
+  size_t nbytes;
+
+  nbytes = url_fread(src->buffer,1,  INPUT_BUF_SIZE,src->infile);
+
+  if (nbytes <= 0) {
+    if (src->start_of_file)	/* Treat empty input file as fatal error */
+      ERREXIT(cinfo, JERR_INPUT_EMPTY);
+    WARNMS(cinfo, JWRN_JPEG_EOF);
+    /* Insert a fake EOI marker */
+    src->buffer[0] = (JOCTET) 0xFF;
+    src->buffer[1] = (JOCTET) JPEG_EOI;
+    nbytes = 2;
+  }
+
+  src->pub.next_input_byte = src->buffer;
+  src->pub.bytes_in_buffer = nbytes;
+  src->start_of_file = FALSE;
+
+  return TRUE;
+}
+
+
+/*
+ * Skip data --- used to skip over a potentially large amount of
+ * uninteresting data (such as an APPn marker).
+  */
+
+void
+url_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+{
+  my_src_ptr src = (my_src_ptr) cinfo->src;
+
+  /* Just a dumb implementation for now.  Could use fseek() except
+   * it doesn't work on pipes.  Not clear that being smart is worth
+   * any trouble anyway --- large skips are infrequent.
+   */
+  if (num_bytes > 0) {
+    while (num_bytes > (long) src->pub.bytes_in_buffer) {
+      num_bytes -= (long) src->pub.bytes_in_buffer;
+      (void) url_fill_input_buffer(cinfo);
+      /* note we assume that fill_input_buffer will never return FALSE,
+       * so suspension need not be handled.
+       */
+    }
+    src->pub.next_input_byte += (size_t) num_bytes;
+    src->pub.bytes_in_buffer -= (size_t) num_bytes;
+  }
+}
+
+
+/*
+ * Terminate source --- called by jpeg_finish_decompress
+ * after all data has been read.  Often a no-op.
+ *
+ * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
+ * application must deal with any cleanup that should happen even
+ * for error exit.
+ */
+
+void
+url_term_source (j_decompress_ptr cinfo)
+{
+  /* no work necessary here */
+}
+
+
+/*
+ * Prepare for input from a stdio stream.
+ * The caller must have already opened the stream, and is responsible
+ * for closing it after finishing decompression.
+ */
+
+void
+jpeg_url_stdio_src (j_decompress_ptr cinfo, URL_FILE * infile)
+{
+  my_src_ptr src;
+
+  /* The source object and input buffer are made permanent so that a series
+   * of JPEG images can be read from the same file by calling jpeg_stdio_src
+   * only before the first one.  (If we discarded the buffer at the end of
+   * one image, we'd likely lose the start of the next one.)
+   * This makes it unsafe to use this manager and a different source
+   * manager serially with the same JPEG object.  Caveat programmer.
+   */
+  if (cinfo->src == NULL) {	/* first time for this JPEG object? */
+    cinfo->src = (struct jpeg_source_mgr *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+				  sizeof(my_source_mgr));
+    src = (my_src_ptr) cinfo->src;
+    src->buffer = (JOCTET *)
+      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+				  INPUT_BUF_SIZE * sizeof(JOCTET));
+  }
+
+  src = (my_src_ptr) cinfo->src;
+  src->pub.init_source = url_init_source;
+  src->pub.fill_input_buffer = url_fill_input_buffer;
+  src->pub.skip_input_data = url_skip_input_data;
+  src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
+  src->pub.term_source = url_term_source;
+  src->infile = infile;
+  src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
+  src->pub.next_input_byte = NULL; /* until buffer loaded */
+}
+
+
+
+
 /* ---------------------------------------------------------------------- */
 /* load                                                                   */
 
 struct jpeg_state {
-    FILE * infile;                /* source file */
+    URL_FILE * infile;                /* source file */
     
     struct jpeg_decompress_struct cinfo;
     struct jpeg_error_mgr jerr;
@@ -31,7 +184,7 @@
 };
 
 static void*
-jpeg_init(FILE *fp, char *filename, struct ida_image_info *i)
+jpeg_init(URL_FILE *fp, char *filename, struct ida_image_info *i)
 {
     struct jpeg_state *h;
     
@@ -41,7 +194,9 @@
 
     h->cinfo.err = jpeg_std_error(&h->jerr);
     jpeg_create_decompress(&h->cinfo);
-    jpeg_stdio_src(&h->cinfo, h->infile);
+
+    jpeg_url_stdio_src(&h->cinfo, h->infile);
+
     jpeg_read_header(&h->cinfo, TRUE);
     h->cinfo.out_color_space = JCS_RGB;
     jpeg_start_decompress(&h->cinfo);
@@ -75,7 +230,7 @@
 {
     struct jpeg_state *h = data;
     jpeg_destroy_decompress(&h->cinfo);
-    fclose(h->infile);
+    url_fclose(h->infile);
     free(h);
 }
 
diff -urN fbi-1.26/loader.c fbi-1.26-patch/loader.c
--- fbi-1.26/loader.c	2003-02-07 10:01:58.000000000 +0000
+++ fbi-1.26-patch/loader.c	2003-08-21 16:57:22.000000000 +0100
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include "curl.h"
 #include "loader.h"
 
 /* ----------------------------------------------------------------------- */
diff -urN fbi-1.26/loader.h fbi-1.26-patch/loader.h
--- fbi-1.26/loader.h	2003-02-07 10:01:58.000000000 +0000
+++ fbi-1.26-patch/loader.h	2003-08-21 16:57:22.000000000 +0100
@@ -16,7 +16,7 @@
     int   moff;
     int   mlen;
     char  *name;
-    void* (*init)(FILE *fp, char *filename, struct ida_image_info *i);
+    void* (*init)(URL_FILE *fp, char *filename, struct ida_image_info *i);
     void  (*read)(unsigned char *dst, unsigned int line, void *data);
     void  (*done)(void *data);
 };
diff -urN fbi-1.26/png.c fbi-1.26-patch/png.c
--- fbi-1.26/png.c	2003-02-07 10:01:58.000000000 +0000
+++ fbi-1.26-patch/png.c	2003-08-21 16:57:22.000000000 +0100
@@ -4,6 +4,7 @@
 #include <errno.h>
 #include <png.h>
 
+#include "curl.h"
 #include "loader.h"
 #ifdef USE_X11
 # include "viewer.h"
@@ -15,7 +16,7 @@
 };
 
 struct png_state {
-    FILE         *infile;
+    URL_FILE         *infile;
     png_structp  png;
     png_infop    info;
     png_bytep    image;
@@ -24,7 +25,7 @@
 };
 
 static void*
-png_init(FILE *fp, char *filename, struct ida_image_info *i)
+png_init(URL_FILE *fp, char *filename, struct ida_image_info *i)
 {
     struct png_state *h;
     int bit_depth, interlace_type;
@@ -102,7 +103,7 @@
 	free(h->image);
     if (h->png)
 	png_destroy_read_struct(&h->png, NULL, NULL);
-    fclose(h->infile);
+    url_fclose(h->infile);
     free(h);
     return NULL;
 }
@@ -144,7 +145,7 @@
 
     free(h->image);
     png_destroy_read_struct(&h->png, &h->info, NULL);
-    fclose(h->infile);
+    url_fclose(h->infile);
     free(h);
 }
 
diff -urN fbi-1.26/ppm.c fbi-1.26-patch/ppm.c
--- fbi-1.26/ppm.c	2003-02-07 10:01:58.000000000 +0000
+++ fbi-1.26-patch/ppm.c	2003-08-21 16:57:22.000000000 +0100
@@ -3,6 +3,7 @@
 #include <string.h>
 #include <errno.h>
 
+#include "curl.h"
 #include "loader.h"
 #ifdef USE_X11
 # include "viewer.h"
@@ -12,13 +13,13 @@
 /* load                                                                   */
 
 struct ppm_state {
-    FILE          *infile;
+    URL_FILE      *infile;
     int           width,height;
     unsigned char *row;
 };
 
 static void*
-pnm_init(FILE *fp, char *filename, struct ida_image_info *i)
+pnm_init(URL_FILE *fp, char *filename, struct ida_image_info *i)
 {
     struct ppm_state *h;
     char line[1024];
@@ -27,12 +28,12 @@
     memset(h,0,sizeof(*h));
 
     h->infile = fp;
-    fgets(line,sizeof(line),fp); /* Px */
-    fgets(line,sizeof(line),fp); /* width height */
+    url_fgets(line,sizeof(line),fp); /* Px */
+    url_fgets(line,sizeof(line),fp); /* width height */
     while ('#' == line[0])
-	fgets(line,sizeof(line),fp); /* skip comments */
+	url_fgets(line,sizeof(line),fp); /* skip comments */
     sscanf(line,"%d %d",&h->width,&h->height);
-    fgets(line,sizeof(line),fp); /* ??? */
+    url_fgets(line,sizeof(line),fp); /* ??? */
     if (0 == h->width || 0 == h->height)
 	goto oops;
     i->width  = h->width;
@@ -42,7 +43,7 @@
     return h;
 
  oops:
-    fclose(fp);
+    url_fclose(fp);
     free(h);
     return NULL;
 }
@@ -52,7 +53,7 @@
 {
     struct ppm_state *h = data;
 
-    fread(dst,h->width,3,h->infile);
+    url_fread(dst,h->width,3,h->infile);
 }
 
 static void
@@ -62,7 +63,7 @@
     unsigned char *src;
     int x;
 
-    fread(h->row,h->width,1,h->infile);
+    url_fread(h->row,h->width,1,h->infile);
     src = h->row;
     for (x = 0; x < h->width; x++) {
 	dst[0] = src[0];
@@ -78,7 +79,7 @@
 {
     struct ppm_state *h = data;
 
-    fclose(h->infile);
+    url_fclose(h->infile);
     free(h->row);
     free(h);
 }
diff -urN fbi-1.26/tiff.c fbi-1.26-patch/tiff.c
--- fbi-1.26/tiff.c	2003-02-07 10:01:58.000000000 +0000
+++ fbi-1.26-patch/tiff.c	2003-08-21 16:57:22.000000000 +0100
@@ -4,6 +4,7 @@
 #include <inttypes.h>
 #include <tiffio.h>
 
+#include "curl.h"
 #include "loader.h"
 #ifdef USE_X11
 # include "viewer.h"
@@ -21,11 +22,11 @@
 };
 
 static void*
-tiff_init(FILE *fp, char *filename, struct ida_image_info *i)
+tiff_init(URL_FILE *fp, char *filename, struct ida_image_info *i)
 {
     struct tiff_state *h;
 
-    fclose(fp);
+    url_fclose(fp);
     h = malloc(sizeof(*h));
     memset(h,0,sizeof(*h));
 
diff -urN fbi-1.26/xwd.c fbi-1.26-patch/xwd.c
--- fbi-1.26/xwd.c	2003-02-07 10:01:58.000000000 +0000
+++ fbi-1.26-patch/xwd.c	2003-08-21 16:57:22.000000000 +0100
@@ -9,6 +9,7 @@
 # include <endian.h>
 #endif
 
+#include "curl.h"
 #include "loader.h"
 #ifdef USE_X11
 # include "viewer.h"
@@ -53,7 +54,7 @@
 /* ----------------------------------------------------------------------- */
 
 struct xwd_state {
-    FILE          *infile;
+    URL_FILE          *infile;
     XWDFileHeader header;
     XWDColor      cmap[256];
     int           width,bpp;
@@ -101,7 +102,7 @@
 
 
 static void*
-xwd_init(FILE *fp, char *filename, struct ida_image_info *i)
+xwd_init(URL_FILE *fp, char *filename, struct ida_image_info *i)
 {
     struct xwd_state *h;
     char *buf;
@@ -111,7 +112,7 @@
     memset(h,0,sizeof(*h));
     h->infile = fp;
 
-    fread(&h->header,sizeof(h->header),1,fp);
+    url_fread(&h->header,sizeof(h->header),1,fp);
 
     if ((be32_to_cpu(h->header.pixmap_format) >sizeof(fmt)/sizeof(char*))   ||
 	(be32_to_cpu(h->header.byte_order)    >sizeof(order)/sizeof(char*)) ||
@@ -141,7 +142,7 @@
 
     size = be32_to_cpu(h->header.header_size)-sizeof(h->header);
     buf = malloc(size);
-    fread(buf,size,1,fp);
+    url_fread(buf,size,1,fp);
     if (debug)
 	fprintf(stderr,"xwd: name=%s\n",buf);
     free(buf);
@@ -165,7 +166,7 @@
 		be32_to_cpu(h->header.colormap_entries));
 	goto oops;
     }
-    fread(&h->cmap,sizeof(XWDColor),be32_to_cpu(h->header.colormap_entries),fp);
+    url_fread(&h->cmap,sizeof(XWDColor),be32_to_cpu(h->header.colormap_entries),fp);
 #if 0
     for (i = 0; i < be32_to_cpu(h->header.colormap_entries); i++)
 	fprintf(stderr, "xwd cmap: %d: "
@@ -202,7 +203,7 @@
     return h;
 	  
  oops:
-    fclose(h->infile);
+    url_fclose(h->infile);
     free(h);
     return NULL;
 }
@@ -276,7 +277,7 @@
 {
     struct xwd_state *h = data;
 
-    fread(h->row,be32_to_cpu(h->header.bytes_per_line),1,h->infile);
+    url_fread(h->row,be32_to_cpu(h->header.bytes_per_line),1,h->infile);
     xwd_parse(dst, line, data);
 }
 
@@ -285,7 +286,7 @@
 {
     struct xwd_state *h = data;
 
-    fclose(h->infile);
+    url_fclose(h->infile);
     free(h->pix);
     free(h->row);
     free(h);

