Index: src/rrd_lastupdate.c
===================================================================
--- src/rrd_lastupdate.c	(revision 1064)
+++ src/rrd_lastupdate.c	(working copy)
@@ -13,7 +13,9 @@ rrd_lastupdate(int argc, char **argv, ti
                  unsigned long *ds_cnt, char ***ds_namv, char ***last_ds) {
     unsigned long i=0;
     char	 *filename;
-    FILE         *in_file;
+    int          in_file;
+    char*	 in_file_addr;
+    off_t	 in_size;
     rrd_t        rrd;
 
     if(argc < 2){
@@ -22,10 +24,9 @@ rrd_lastupdate(int argc, char **argv, ti
     }
     filename = argv[1];
 
-    if(rrd_open(filename,&in_file,&rrd, RRD_READONLY)==-1){
+    in_file_addr = rrd_open(filename, &in_file, &in_size, &rrd, RRD_READONLY);
+    if (in_file_addr == NULL)
 	return(-1);
-    }
-    fclose(in_file);
 
     *last_update=rrd.live_head->last_up;
     *ds_cnt = rrd.stat_head->ds_cnt;
@@ -50,5 +51,6 @@ rrd_lastupdate(int argc, char **argv, ti
     }
 
     rrd_free(&rrd);
+    rrd_close(in_file_addr, in_size);
     return(0); 
 }
Index: src/rrd_info.c
===================================================================
--- src/rrd_info.c	(revision 1064)
+++ src/rrd_info.c	(working copy)
@@ -87,10 +87,13 @@ rrd_info_r(char *filename) {   
     rrd_t        rrd;
     info_t       *data,*cd;
     infoval      info;
+    char*	 in_file_addr;
+    off_t	 in_file_size;
 	enum cf_en   current_cf;
 	enum dst_en  current_ds;
 
-    if(rrd_open(filename,&in_file,&rrd, RRD_READONLY)==-1){
+    in_file_addr = rrd_open(filename,&in_file,&in_file_size,&rrd, RRD_READONLY);
+    if (in_file_addr == NULL) {
 	return(NULL);
     }
     fclose(in_file);
Index: src/rrd_last.c
===================================================================
--- src/rrd_last.c	(revision 1064)
+++ src/rrd_last.c	(working copy)
@@ -23,17 +23,20 @@ rrd_last(int argc, char **argv)
 time_t
 rrd_last_r(const char *filename)
 {
-    FILE	*in_file;
+    int	in_file;
     time_t       lastup;
+    off_t	 in_size;
+    char*	 in_file_addr;
 
     rrd_t	 rrd;
 
-    if(rrd_open(filename, &in_file, &rrd, RRD_READONLY)==-1){
+    in_file_addr = rrd_open(filename, &in_file, &in_size, &rrd, RRD_READONLY);
+    if (in_file_addr == NULL)
         return(-1);
-    }
+
     lastup = rrd.live_head->last_up;
     rrd_free(&rrd);
-    fclose(in_file);
+    rrd_close(in_file_addr, in_size);
     return(lastup);
 }
 
Index: src/rrd_thread_safe.c
===================================================================
--- src/rrd_thread_safe.c	(revision 1064)
+++ src/rrd_thread_safe.c	(working copy)
@@ -52,7 +52,7 @@ struct rrd_context *rrd_get_context(void
 const char *rrd_strerror(int err) {
     struct rrd_context *ctx = rrd_get_context();
     if (strerror_r(err, ctx->lib_errstr, ctx->errlen)) 
-         return "strerror_r faild. sorry!"; 
+         return "strerror_r failed. sorry!"; 
     else 
          return ctx->lib_errstr; 
 }
Index: src/rrd_tool.h
===================================================================
--- src/rrd_tool.h	(revision 1064)
+++ src/rrd_tool.h	(working copy)
@@ -171,7 +171,9 @@ void rrd_free(rrd_t *rrd);
 void rrd_freemem(void *mem);
 void rrd_init(rrd_t *rrd);
 
-int rrd_open(const char *file_name, FILE **in_file, rrd_t *rrd, int rdwr);
+char* rrd_open(const char *file_name, int *in_file, off_t *in_file_size,
+		rrd_t *rrd, int rdwr);
+int rrd_close(char *in_file_addr, off_t in_file_size);
 int readfile(const char *file, char **buffer, int skipfirst);
 
 #define RRD_READONLY    0
Index: src/rrd_open.c
===================================================================
--- src/rrd_open.c	(revision 1064)
+++ src/rrd_open.c	(working copy)
@@ -68,34 +68,41 @@
 /* open a database file, return its header and a open filehandle */
 /* positioned to the first cdp in the first rra */
 
-int
-rrd_open(const char *file_name, FILE **in_file, rrd_t *rrd, int rdwr)    
+char *
+rrd_open(const char *file_name, int *in_file, off_t *in_sz, rrd_t *rrd, int rdwr)
 {
+    mode_t mode = S_IRUSR;
+    int version, prot = PROT_READ;
+    off_t offset = 0;
+    char *data;
+	struct stat statb;
 
-    
-    char *mode = NULL;
-    int version;
-    
     rrd_init(rrd);
-    if (rdwr == RRD_READONLY) {
-        mode = "rb";
-    } else {
-        mode = "rb+";
+	if (rdwr != RRD_READONLY) {
+		mode |= S_IWUSR;
+		prot |= PROT_WRITE;
     }
     
-    if (((*in_file) = fopen(file_name,mode)) == NULL ){
+    if (((*in_file) = open(file_name,mode)) < 0 ){
         rrd_set_error("opening '%s': %s",file_name, rrd_strerror(errno));
-        return (-1);
+        return NULL;
     }
+	/* ???: length = lseek(*in_file, 0, SEEK_END); */
+	/* ??? locking the whole area of the file may overdo it a bit, does it? */
+	if ((fstat(*in_file, &statb)) < 0) {
+		rrd_set_error("fstat '%s': %s",file_name, rrd_strerror(errno));
+		goto out_close;
+	}
+	*in_sz = statb.st_size;
 
 #ifdef HAVE_POSIX_FADVISE
     /* In general we need no read-ahead when dealing with rrd_files.
        When we stop reading, it is highly unlikely that we start up again.
        In this manner we actually save time and diskaccess (and buffer cache).
        Thanks to Dave Plonka for the Idea of using POSIX_FADV_RANDOM here. */       
-    if (0 != posix_fadvise(fileno(*in_file), 0, 0, POSIX_FADV_RANDOM)) {
+    if (0 != posix_fadvise(*in_file, 0, 0, POSIX_FADV_RANDOM)) {
         rrd_set_error("setting POSIX_FADV_RANDOM on '%s': %s",file_name, rrd_strerror(errno));
-        fclose(*in_file);
+        close(fd);
         return(-1);
      }    
 #endif
@@ -109,72 +116,79 @@ rrd_open(const char *file_name, FILE **i
            }
         }
 */
-    
-#define MYFREAD(MYVAR,MYVART,MYCNT) \
-    if ((MYVAR = malloc(sizeof(MYVART) * MYCNT)) == NULL) {\
-        rrd_set_error("" #MYVAR " malloc"); \
-        fclose(*in_file); \
-        return (-1); } \
-    fread(MYVAR,sizeof(MYVART),MYCNT, *in_file); 
-
 
-    MYFREAD(rrd->stat_head, stat_head_t,  1)
+    data = mmap(0, *in_sz, prot, MAP_SHARED, *in_file, offset);
     /* lets see if the first read worked */
-    if (ferror( *in_file ) || feof(*in_file)) {
-        rrd_set_error("reading the cookie off %s faild",file_name);
-        fclose(*in_file);
-        return(-1);
-    }        
+    if (data == MAP_FAILED) {
+        rrd_set_error("reading the cookie off %s failed",file_name);
+        goto out_close;
+    }
+    rrd->stat_head = (stat_head_t*)(data + offset);
+	offset += sizeof(stat_head_t);
 
         /* lets do some test if we are on track ... */
-        if (strncmp(rrd->stat_head->cookie,RRD_COOKIE,4) != 0){
-            rrd_set_error("'%s' is not an RRD file",file_name);
-            free(rrd->stat_head);
-            rrd->stat_head = NULL; 
-            fclose(*in_file);
-            return(-1);}
-
-        if (rrd->stat_head->float_cookie != FLOAT_COOKIE){
-            rrd_set_error("This RRD was created on other architecture");
-            free(rrd->stat_head);
-            rrd->stat_head = NULL; 
-            fclose(*in_file);
-            return(-1);}
+	if (memcmp(rrd->stat_head->cookie,RRD_COOKIE,sizeof(RRD_COOKIE)) != 0) {
+		rrd_set_error("'%s' is not an RRD file",file_name);
+		goto out_nullify_head;
+	}
+
+	if (rrd->stat_head->float_cookie != FLOAT_COOKIE){
+		rrd_set_error("This RRD was created on other architecture");
+		goto out_nullify_head;
+	}
 
     version = atoi(rrd->stat_head->version);
 
-        if (version > atoi(RRD_VERSION)){
+	if (version > atoi(RRD_VERSION)) {
             rrd_set_error("can't handle RRD file version %s",
                         rrd->stat_head->version);
-            free(rrd->stat_head);
-            rrd->stat_head = NULL; 
-            fclose(*in_file);
-            return(-1);}
+            goto out_nullify_head;
+	}
+
 
+	rrd->ds_def = (ds_def_t*)(data + offset);
+	offset += sizeof(ds_def_t) * rrd->stat_head->ds_cnt;
+
+	rrd->rra_def = (rra_def_t*)(data + offset);
+	offset += sizeof(rra_def_t) * rrd->stat_head->rra_cnt;
 
-    MYFREAD(rrd->ds_def,    ds_def_t,     rrd->stat_head->ds_cnt)
-    MYFREAD(rrd->rra_def,   rra_def_t,    rrd->stat_head->rra_cnt)
     /* handle different format for the live_head */
-    if(version < 3) {
+    if (version < 3) {
             rrd->live_head = (live_head_t *)malloc(sizeof(live_head_t));
-            if(rrd->live_head == NULL) {
+            if (rrd->live_head == NULL) {
                 rrd_set_error("live_head_t malloc");
-                fclose(*in_file); 
-                return (-1);
+                goto out_close;
             }
-                fread(&rrd->live_head->last_up, sizeof(long), 1, *in_file); 
-                rrd->live_head->last_up_usec = 0;
-    }
-    else {
-            MYFREAD(rrd->live_head, live_head_t, 1)
+		memmove(&rrd->live_head->last_up, data+offset, sizeof(long));
+		rrd->live_head->last_up_usec = 0;
+    } else {
+
+            rrd->live_head = (live_head_t*)(data + offset);
+			offset += sizeof(live_head_t);
     }
-    MYFREAD(rrd->pdp_prep,  pdp_prep_t,   rrd->stat_head->ds_cnt)
-    MYFREAD(rrd->cdp_prep,  cdp_prep_t,   (rrd->stat_head->rra_cnt
-                                             * rrd->stat_head->ds_cnt))
-    MYFREAD(rrd->rra_ptr,   rra_ptr_t,    rrd->stat_head->rra_cnt)
-#undef MYFREAD
 
-    return(0);
+	rrd->pdp_prep = (pdp_prep_t*)(data + offset);
+	offset += sizeof(pdp_prep_t) * rrd->stat_head->ds_cnt;
+
+	rrd->cdp_prep = (cdp_prep_t*)(data + offset);
+
+	offset += sizeof(cdp_prep_t) *
+				(rrd->stat_head->rra_cnt * rrd->stat_head->ds_cnt);
+
+	rrd->rra_ptr = (rra_ptr_t*)(data + offset);
+	offset += sizeof(rra_ptr_t) * rrd->stat_head->rra_cnt;
+
+	/* we should close(*in_file); here, the mapping is still valid anyway */
+    return(data);
+out_nullify_head:
+    rrd->stat_head = NULL;
+out_close:
+    close(*in_file);
+    return NULL;
+}
+
+int rrd_close(char *in_file_addr, off_t in_file_size) {
+	return munmap(in_file_addr, in_file_size);
 }
 
 void rrd_init(rrd_t *rrd)
@@ -191,22 +205,21 @@ void rrd_init(rrd_t *rrd)
 
 void rrd_free(rrd_t *rrd)
 {
-    if (rrd->stat_head) free(rrd->stat_head);
-    if (rrd->ds_def) free(rrd->ds_def);
-    if (rrd->rra_def) free(rrd->rra_def);
-    if (rrd->live_head) free(rrd->live_head);
-    if (rrd->rra_ptr) free(rrd->rra_ptr);
-    if (rrd->pdp_prep) free(rrd->pdp_prep);
-    if (rrd->cdp_prep) free(rrd->cdp_prep);
-    if (rrd->rrd_value) free(rrd->rrd_value);
+//    free(rrd->stat_head);
+//    free(rrd->ds_def);
+//    free(rrd->rra_def);
+//if(version < 3)	free(rrd->live_head);
+//    free(rrd->rra_ptr);
+//    free(rrd->pdp_prep);
+//    free(rrd->cdp_prep);
+//    free(rrd->rrd_value);
 }
 
 /* routine used by external libraries to free memory allocated by
  * rrd library */
 void rrd_freemem(void *mem)
 {
-
-    if (mem) free(mem);
+	free(mem);
 }
 
 int readfile(const char *file_name, char **buffer, int skipfirst){
@@ -251,4 +264,4 @@ int readfile(const char *file_name, char
     return writecnt;
 }
 
-
+/* vi: set ts=4 sw=4: */
Index: configure.ac
===================================================================
--- configure.ac	(revision 1064)
+++ configure.ac	(working copy)
@@ -70,10 +70,20 @@ char *strchr (), *strrchr ();
 # endif
 #endif
 
+#if defined(HAVE_OPEN)
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+
+#if defined(HAVE_MADVISE)
+#include <sys/mman.h>
+#endif
+
 /* enable posix_fadvise on linux */
 #if defined(HAVE_POSIX_FADVISE) && defined(HAVE_FCNTL_H)
-#include <fcntl.h>
 #define __USE_XOPEN2K 1
+#include <fcntl.h>
 #endif
 
 #ifdef NO_NULL_REALLOC
@@ -248,7 +258,7 @@ AC_C_BIGENDIAN
 dnl for each function found we get a definition in config.h 
 dnl of the form HAVE_FUNCTION
 
-AC_CHECK_FUNCS(tzset mbstowcs opendir readdir chdir chroot getuid setlocale strerror strerror_r snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday posix_fadvise)
+AC_CHECK_FUNCS(tzset mbstowcs opendir readdir chdir chroot getuid setlocale strerror strerror_r snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday open close madvise)
 
 
 if test "x$enable_mmap" = xyes; then
