diff --git a/src/server/Makefile.in b/src/server/Makefile.in
index 9c8f776fe3d9561f1bde83b85324c97949c474cd..03b18730560f65bd85072535769edc1f3573bf34 100755
--- a/src/server/Makefile.in
+++ b/src/server/Makefile.in
@@ -1,5 +1,5 @@
 #
-# Generated from: Makefile.src,v 1.29 1996/08/25 19:53:59 ceder Exp 
+# Generated from: Makefile.src,v 1.30 1997/09/13 15:31:45 byers Exp 
 # Copyright (C) 1991, 1993, 1994, 1995, 1996  Lysator Academic Computer Association.
 #
 # This file is part of the LysKOM server.
diff --git a/src/server/aux-items.c b/src/server/aux-items.c
index 7a32a34e3071a81a442d3e363f62a07a029dbbd0..3b1663fef4b1425c16591368d3d4c919949c216f 100644
--- a/src/server/aux-items.c
+++ b/src/server/aux-items.c
@@ -1,5 +1,5 @@
 /*
- * $Id: aux-items.c,v 1.1 1997/09/13 15:31:55 byers Exp $
+ * $Id: aux-items.c,v 1.2 1997/10/23 12:37:20 byers Exp $
  * Copyright (C) 1994, 1995, 1996  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -36,6 +36,7 @@
 #include "manipulate.h"
 #include "aux-items.h"
 #include "kom-errno.h"
+#include "kom-memory.h"
 #include "async.h"
 #include "com.h"
 #include "connections.h"
@@ -531,7 +532,7 @@ aux_inherit_items(Aux_item_list *target,
                                    ))
                 continue;
 
-            item = copy_aux_item(parent->items[i]);
+            copy_aux_item(&item, &parent->items[i]);
             prepare_aux_item(&item, parent->items[i].creator, def);
             if (item.inherit_limit != 0)
                 item.inherit_limit -= 1;
@@ -541,25 +542,6 @@ aux_inherit_items(Aux_item_list *target,
     }
 }
 
-/*
- * copy_aux_item
- *
- * Create a copy of an aux item by duplicating duplicable fields
- * and duplicating all dynamically allocated memory
- */
-
-Aux_item copy_aux_item(Aux_item item)
-{
-    Aux_item new;
-
-    new = item;
-    new.data = EMPTY_STRING;
-    s_strcpy(&new.data, item.data);
-
-    return new;
-}
-
-
 /*
  * filter_aux_item_list
  *
@@ -815,8 +797,9 @@ void text_stat_add_aux_item_list(Text_stat *text_s,
         item_list->items[i].aux_no = text_s->highest_aux;
         item_list->items[i].creator = item_creator;
         item_list->items[i].sent_at = time(NULL);
-        text_s->aux_item_list.items[text_s->aux_item_list.length]
-            = copy_aux_item(item_list->items[i]);
+        copy_aux_item(
+            &text_s->aux_item_list.items[text_s->aux_item_list.length],
+            &item_list->items[i]);
         text_s->aux_item_list.length += 1;
     }
 }
@@ -897,8 +880,8 @@ conf_stat_add_aux_item_list(Conference    *conf,
         item_list->items[i].aux_no = conf->highest_aux;
         item_list->items[i].creator = item_creator;
         item_list->items[i].sent_at = time(NULL);
-        conf->aux_item_list.items[conf->aux_item_list.length]
-            = copy_aux_item(item_list->items[i]);
+        copy_aux_item(&conf->aux_item_list.items[conf->aux_item_list.length],
+                      &item_list->items[i]);
         conf->aux_item_list.length += 1;
     }
 }
@@ -965,8 +948,8 @@ system_add_aux_item_list(Info    *info,
         item_list->items[i].aux_no = info->highest_aux_no;
         item_list->items[i].creator = item_creator;
         item_list->items[i].sent_at = time(NULL);
-        info->aux_item_list.items[info->aux_item_list.length]
-            = copy_aux_item(item_list->items[i]);
+        copy_aux_item(&info->aux_item_list.items[info->aux_item_list.length],
+                      &item_list->items[i]);
         info->aux_item_list.length += 1;
     }
 }
diff --git a/src/server/aux-items.h b/src/server/aux-items.h
index a5a54f50d82cbb79b643609b172ca3d1210284d0..45728855ba33c3ab5b91dfa715a926b2e454cc0a 100644
--- a/src/server/aux-items.h
+++ b/src/server/aux-items.h
@@ -1,5 +1,5 @@
 /*
- * $Id: aux-items.h,v 1.1 1997/09/13 15:31:56 byers Exp $
+ * $Id: aux-items.h,v 1.2 1997/10/23 12:37:21 byers Exp $
  * Copyright (C) 1994, 1995, 1996  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -48,7 +48,7 @@
     (list).items =                                                      \
         srealloc((list).items,                                          \
                  ((list).length + 1) * sizeof(Aux_item));               \
-    (list).items[(list).length] = copy_aux_item(item);                  \
+    copy_aux_item(&(list).items[(list).length], &item);                 \
     (counter) += 1;                                                     \
     (list).items[(list).length].aux_no = (counter);                     \
     (list).length += 1;                                                 \
@@ -88,12 +88,6 @@ extern Aux_item_definition empty_aux_item_definition;
 
 
 
-/* Return a copy of item. If you think you need to
- * call this, think again. */
-
-Aux_item copy_aux_item(Aux_item item);
-
-
 
 /* Inerit items from parent to target. counter is a pointer to
  * highest_aux_item or equivalent. target_creator is the creator
diff --git a/src/server/cache-node.h b/src/server/cache-node.h
index 942fbd58c9c2a9e9d327a53b2d41af68c2ce2586..ea25c1facf4ab0a637a399601f3be65497e3ea5c 100644
--- a/src/server/cache-node.h
+++ b/src/server/cache-node.h
@@ -1,5 +1,5 @@
 /*
- * $Id: cache-node.h,v 0.10 1995/11/02 21:48:24 ceder Exp $
+ * $Id: cache-node.h,v 0.11 1997/10/23 12:37:22 byers Exp $
  * Copyright (C) 1991, 1993, 1994, 1995  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -23,7 +23,7 @@
  * Please mail bug reports to bug-lyskom@lysator.liu.se. 
  */
 /*
- * $Id: cache-node.h,v 0.10 1995/11/02 21:48:24 ceder Exp $
+ * $Id: cache-node.h,v 0.11 1997/10/23 12:37:22 byers Exp $
  *
  * cache-node.h
  */
@@ -31,15 +31,22 @@
 typedef struct cache_node {
     struct {
 	unsigned int	exists : 1;
-	unsigned int	dirty : 1;		/* Is *ptr modified? */
+	unsigned int	dirty : 1;    /* Is *ptr modified? */
+        unsigned int    snapshot : 1; /* We have a valid snapshot */
+        unsigned int    saved_sirty : 1; /* Saved a dirty copy */
     } s;
     void   *snap_shot;		/* Dirty data to be written to file B. */
 				/* (Dirty relative to file A). */
     void   *ptr;		/* In-core data. */
     long   pos;			/* Position to element in file A. */
     long   size;		/* Size on disk. */
+#ifdef FASTSAVE
+    long   saved_pos;           /* Position saved in case of recover */
+    long   saved_size;          /* Size saved in case of recover */
+#else
     long   pos_b;		/* Position to element in file B. */
     long   size_b;		/* Size in file B. */
+#endif
     struct cache_node *prev;	/* Points towards most recently used. */
     struct cache_node *next;	/* Points towards least recently used. */
     int	lock_cnt;
diff --git a/src/server/kom-memory.h b/src/server/kom-memory.h
index 078713b912da78f14c7e16c5969429efaaac174f..5544aa9211511f20a6cbaa39d8d52745f250611f 100644
--- a/src/server/kom-memory.h
+++ b/src/server/kom-memory.h
@@ -1,5 +1,5 @@
 /*
- * $Id: kom-memory.h,v 1.6 1997/09/13 15:32:09 byers Exp $
+ * $Id: kom-memory.h,v 1.7 1997/10/23 12:37:23 byers Exp $
  * Copyright (C) 1991, 1993, 1994, 1996  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -23,7 +23,7 @@
  * Please mail bug reports to bug-lyskom@lysator.liu.se. 
  */
 /*
- * $Id: kom-memory.h,v 1.6 1997/09/13 15:32:09 byers Exp $
+ * $Id: kom-memory.h,v 1.7 1997/10/23 12:37:23 byers Exp $
  *
  * The time has come to get some order into this mess.
  *
@@ -116,6 +116,10 @@ extern void init_who_info_old (Who_info_old *w);
 /* Aux_item_list */
 
 extern void free_aux_item_list (Aux_item_list *list);
+extern void copy_aux_item_list (Aux_item_list *dest, Aux_item_list *src);
+extern void init_aux_item_list (Aux_item_list *list);
+
+extern void copy_aux_item (Aux_item *dest, Aux_item *src);
 
 /*
  * Other kind of functions 
diff --git a/src/server/memory.c b/src/server/memory.c
index c27ce0b40a623612e13a0cc4fc823673d2b9887b..a4ef1eabef56557b384abe58706f634e7090192a 100644
--- a/src/server/memory.c
+++ b/src/server/memory.c
@@ -1,5 +1,5 @@
 /*
- * $Id: memory.c,v 0.20 1997/09/13 15:32:13 byers Exp $
+ * $Id: memory.c,v 0.21 1997/10/23 12:37:25 byers Exp $
  * Copyright (C) 1991, 1992, 1993, 1994, 1996  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -28,7 +28,7 @@
  * These functions should be used instead of smalloc/srealloc.
  */
 
-static char *rcsid = "$Id: memory.c,v 0.20 1997/09/13 15:32:13 byers Exp $";
+static char *rcsid = "$Id: memory.c,v 0.21 1997/10/23 12:37:25 byers Exp $";
 #include "rcs.h"
 USE(rcsid);
 
@@ -109,6 +109,7 @@ clear_conference(Conference *confp)
     s_clear(&confp->name);
     clear_member_list(&confp->members);
     clear_text_list(&confp->texts);
+    free_aux_item_list(&confp->aux_item_list);
     init_conference(confp);
 }
 
@@ -123,6 +124,8 @@ copy_conference (Conference *o)
     s_strcpy(&c->name, o->name);
     c->members = copy_member_list(o->members);
     c->texts = copy_text_list(o->texts);
+    copy_aux_item_list(&c->aux_item_list,
+                       &o->aux_item_list);
     return c;
 }
 
@@ -142,6 +145,7 @@ init_conference  (Conference *c)
     c->name = EMPTY_STRING;
     init_member_list(&c->members);
     init_text_list(&c->texts);
+    init_aux_item_list(&c->aux_item_list);
 }
 
 /* Dynamic_session_info */
@@ -553,13 +557,8 @@ clear_text_stat(Text_stat *t)
 	}
     }
 
-    for (i = 0; i < t->aux_item_list.length; i++)
-    {
-        s_clear(&t->aux_item_list.items[i].data);
-    }
-
-    sfree(t->aux_item_list.items);
     sfree(t->misc_items);
+    free_aux_item_list(&t->aux_item_list);
     init_text_stat(t);
 }
 
@@ -572,11 +571,8 @@ copy_text_stat(Text_stat *t)
     *c = *t;
     c->misc_items = smalloc(c->no_of_misc * sizeof(Misc_info));
     memcpy(c->misc_items, t->misc_items, c->no_of_misc * sizeof(Misc_info));
-    c->aux_item_list.items = 
-      smalloc(c->aux_item_list.length * sizeof(Aux_item));
-    memcpy(c->aux_item_list.items, 
-	   t->aux_item_list.items, 
-	   c->aux_item_list.length * sizeof(Aux_item));
+    copy_aux_item_list(&c->aux_item_list,
+                       &t->aux_item_list);
     return c;
 }
 
@@ -592,8 +588,7 @@ init_text_stat  (Text_stat *t)
     t->no_of_misc = 0;
     t->highest_aux = 0;
     t->misc_items = NULL;
-    t->aux_item_list.length = 0;
-    t->aux_item_list.items  = NULL;
+    init_aux_item_list(&t->aux_item_list);
 }
 
 /* struct tm */
@@ -665,6 +660,35 @@ free_aux_item_list(Aux_item_list *list)
     list->items = NULL;
 }
 
+void
+copy_aux_item_list(Aux_item_list *dest, Aux_item_list *src)
+{
+    unsigned long   i;
+
+    *dest = *src;
+    dest->items = smalloc(sizeof(Aux_item) * src->length);
+    for (i = 0; i < src->length; i++)
+    {
+        copy_aux_item(&dest->items[i], &src->items[i]);
+    }
+}
+
+void
+init_aux_item_list(Aux_item_list *list)
+{
+    list->length = 0;
+    list->items = NULL;
+}
+
+void
+copy_aux_item(Aux_item *dest, Aux_item *src)
+{
+    *dest = *src;
+    dest->data = EMPTY_STRING;
+    s_strcpy(&dest->data, src->data);
+}
+
+
 /*
  * Other kind of functions 
  */
diff --git a/src/server/simple-cache.c b/src/server/simple-cache.c
index ce5c091a26ebb89a0a0a6a4199bd2196ff96e1ff..aa51e5881d365aec9b6059446f341b2853917ccc 100644
--- a/src/server/simple-cache.c
+++ b/src/server/simple-cache.c
@@ -1,5 +1,5 @@
 /*
- * $Id: simple-cache.c,v 0.63 1997/09/13 15:32:40 byers Exp $
+ * $Id: simple-cache.c,v 0.64 1997/10/23 12:37:26 byers Exp $
  * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996  Lysator Academic Computer Association.
  *
  * This file is part of the LysKOM server.
@@ -31,9 +31,10 @@
  * New database format with texts in their own file by Inge Wallin.
  *
  * New save algorithm by ceder.
+ * Attempt at newer algorithm by byers (FASTSAVE)
  */
 
-static char *rcsid = "$Id: simple-cache.c,v 0.63 1997/09/13 15:32:40 byers Exp $";
+static char *rcsid = "$Id: simple-cache.c,v 0.64 1997/10/23 12:37:26 byers Exp $";
 #include "rcs.h"
 USE(rcsid);
 
@@ -117,6 +118,9 @@ EXPORT Conf_no       *conf_table  = NULL; /* Used in conference.c. */
 static FILE	*text_file= NULL;
 static FILE	*file_a = NULL;	/* Current file. */
 static FILE	*file_b = NULL;	/* File under construction. */
+#ifdef FASTSAVE
+static FILE     *file_b_r = NULL; /* Read from file under construction */
+#endif
 
 /*
  * Four state variables for the background save.
@@ -146,7 +150,9 @@ static enum {
  *  sync_wait          SYNC_RETRY_INTERVAL  sync_save_conf
  */
 
+#ifndef FASTSAVE
 static long sync_next;
+#endif
 
 static Conf_no highest_conf_no;
 static Text_no highest_text_no;
@@ -1372,8 +1378,11 @@ is_clean(const char *fn)
     if ( (fp = fopen(fn, "rb")) == NULL )
 	return FALSE;
 
-    if ( getc(fp) == 'C' && getc(fp) == 'L' && getc(fp) == 'E'
-	&& getc(fp) == 'A' && getc(fp) == 'N' )
+    if ( getc(fp) == 'C' &&
+         getc(fp) == 'L' &&
+         getc(fp) == 'E' &&
+         getc(fp) == 'A' &&
+         getc(fp) == 'N' )
     {
 	fclose(fp);
 	return TRUE;
@@ -1422,6 +1431,7 @@ pre_sync(void)
     highest_text_no = next_text_num;
     highest_conf_no = next_free_num;
 
+#ifndef FASTSAVE
     for ( i = 1; i < highest_conf_no; i++ )
     {
 	node = get_conf_node(i);
@@ -1517,6 +1527,7 @@ pre_sync(void)
 	    }
 	}
     }
+#endif
 
     /* All marking is done. Now open file B. */
     
@@ -1532,9 +1543,12 @@ pre_sync(void)
     {
 	log("pre_sync: Save in progress aborted.\n");
 	fclose(file_b);
+#ifdef FASTSAVE
+        file_b = NULL;
+#endif
     }
 
-    if ( (file_b=fopen(param.datafile_name, "wb") ) == NULL )
+    if ( (file_b   = fopen(param.datafile_name, "wb") ) == NULL )
     {
 	log("WARNING: pre_sync: can't open file to save in.\n");
 	sync_state = sync_wait;
@@ -1542,6 +1556,18 @@ pre_sync(void)
 	return;
     }
 
+#ifdef FASTSAVE
+    if ( (file_b_r = fopen(param.datafile_name, "rb") ) == NULL )
+    {
+        fclose(file_b);
+        file_b = NULL;
+	log("WARNING: pre_sync: can't open file to save in for reading.\n");
+	sync_state = sync_wait;
+
+	return;
+    }
+#endif
+
     
     
     fprintf(file_b, "DIRTY:%05ld\n", 2L);      /* DIRTY-FLAG and VERSION*/
@@ -1551,7 +1577,12 @@ pre_sync(void)
     foutput_info(file_b, &kom_info);
     fprintf(file_b, "\n");
     sync_state = sync_save_conf;
+#ifdef FASTSAVE
+    next_text_to_sync = 1;
+    next_conf_to_sync = 1;
+#else
     sync_next = 1;
+#endif
 }
 
 static void
@@ -1608,23 +1639,34 @@ save_one_conf(void)
 {
     Cache_node *cn;
     
+#ifdef FASTSAVE
+    if (next_conf_to_sync < highest_conf_no)
+#else
     if (sync_next < highest_conf_no)
+#endif
     {
 	cn = get_conf_node (sync_next);
 
 	if ( cn == NULL )
 	{
-/*	    putc('@', file_b);
-	    putc('\n', file_b); */
 	}
 	else 
 	{
+#ifdef FASTSAVE
+            cn->saved_pos = cn->pos;
+            cn->pos = ftell(file_b);
+            cn->s.saved_dirty = cn->s.dirty;
+#else
 	    cn->pos_b = ftell(file_b);
-
+#endif
+            
 	    if ( cn->snap_shot != NULL )
 	    {
 		fprintf(file_b, "C %ld ", sync_next);
 		foutput_conference(file_b, cn->snap_shot);
+#ifdef FASTSAVE
+                free_conference( cn->snap_shot );
+#endif
 	    }
 	    else if ( cn->s.dirty == 0 && cn->ptr != NULL )
 	    {
@@ -1637,14 +1679,28 @@ save_one_conf(void)
 	    }
 
 	    putc('\n', file_b);
+#ifdef FASTSAVE
+            cn->saved_size = cn->size;
+	    cn->size = ftell(file_b) - cn->pos;
+#else
 	    cn->size_b = ftell(file_b) - cn->pos_b;
+            cn->s.dirty = 0;
+#endif
 	}
+#ifdef FASTSAVE
+        next_conf_to_sync += 1;
+#else
 	sync_next++;
+#endif
     }
     else			/* All conferences are written. */
     {
+#ifdef FASTSAVE
+        sync_stat = sync_save_conf;
+#else
 	sync_next = 1;
 	sync_state = sync_save_pers;
+#endif
     }
 }
 
@@ -1663,14 +1719,15 @@ save_one_pers(void)
 {
     Cache_node *cn;
     
+#ifdef FASTSAVE
+    restart_kom("Attempt to save one person in FASTSAVE mode (can't happen.)");
+#endif
     if (sync_next < highest_conf_no)
     {
 	cn = get_pers_node (sync_next);
 
 	if ( cn == NULL )
 	{
-/*	    putc('@', file_b);
-	    putc('\n', file_b); */
 	}
 	else 
 	{
@@ -1768,39 +1825,62 @@ save_one_text(void)
     long offset;
     long offset2;
     
+#ifdef FASTSAVE
+    while (next_text_to_sync < highest_text_no)
+#else
     while (sync_next < highest_text_no)
+#endif
     {
 	cn = get_text_node(sync_next);
 
 	if ( cn == NULL )
 	{
-/*	    putc('@', file_b);
-	    putc('\n', file_b); */
-
+#ifdef FASTSAVE
+            next_text_to_sync += 1;
+#else
 	    sync_next++;
+#endif
 	    continue;
 	}
 	else 
 	{
+#ifdef FASTSAVE
+            cn->saved_pos = cn->pos;
+	    cn->pos = ftell(file_b);
+            cn->s.saved_dirty = cn->s.dirty;
+#else
 	    cn->pos_b = ftell(file_b);
+#endif
 
 	    if ( cn->snap_shot != NULL )
 	    {
 		fprintf(file_b, "T %ld", sync_next);
 		foutput_text_stat(file_b, cn->snap_shot);
+#ifdef FASTSAVE
+                free_text_stat( cn->snap_shot );
+#endif
 	    }
 	    else if ( cn->s.dirty == 0 && cn->ptr != NULL )
 	    {
 		fprintf(file_b, "T %ld", sync_next);
 		foutput_text_stat(file_b, cn->ptr);
+
 	    }
 	    else
+            {
 		copy_file(file_a, file_b, cn->pos, cn->size - 1, sync_next);
+            }
 
 	    putc('\n', file_b);
+#ifdef FASTSAVE
+	    cn->size = ftell(file_b) - cn->pos;
+	    next_text_to_sync += 1;
+            cn->s.dirty = 0;
+#else
 	    cn->size_b = ftell(file_b) - cn->pos_b;
-
 	    sync_next++;
+#endif
+
 	    break;
 	}
 	/*NOTREACHED*/
@@ -1808,7 +1888,11 @@ save_one_text(void)
     }
 
     /* If all texts are written, do some clean-up. */
+#ifdef FASTSAVE
+    if (next_text_to_sync == highest_text_no)
+#else
     if (sync_next == highest_text_no)
+#endif
     {
 	if ( ferror(file_b) != 0 )
 	{
@@ -1870,6 +1954,20 @@ save_one_text(void)
 	    return;
 	}
 
+
+#ifdef FASTSAVE
+        if ( fclose(file_b_r) != 0 )
+        {
+            file_b_r = NULL;
+
+	    log("Sync: fclose() of reader failed in save_one_text.  Retrying.\n");
+	    remove(param.datafile_name);
+	    sync_state = sync_wait;
+	    return;
+        }
+        file_b_r = NULL;
+#endif
+
 	file_b = fopen(param.datafile_name, "rb");
 	if (file_b == NULL)
 	{
@@ -1932,14 +2030,16 @@ sync_part(void)
 	save_one_conf();
 	break;
 
+#ifndef FASTSAVE
     case sync_save_pers:
 	save_one_pers();
 	break;
+#else
 
     case sync_save_text:
 	save_one_text();
 	break;
-
+        
     case sync_ready:
 	sync_state = sync_idle;
 	return TRUE;
@@ -1977,6 +2077,13 @@ sync_part(void)
 	log("sync: Error saving new file. Retrying.\n");
 	fclose(file_b);
 	file_b = NULL;
+#ifdef FASTSAVE
+        if (file_b_r != NULL)
+        {
+            fclose(file_b_r);
+            file_b_r = NULL;
+        }
+#endif
 	remove(param.datafile_name);
 	sync_state = sync_wait;
 	break;