2004-11-15 Andrew J. Schorr <ajschorr@alumni.princeton.edu>

	* memory.c: (zerror) Use zlog_err instead of fprintf to stderr.
	  Instead of exiting, log currenty memory usage and then abort.
	  (log_memstats) New function to log memory statistics, called by
	  zerror.
	  (show_memory_all) Loop over new mlists array instead of calling
	  show_memory_vty separately for each memory_list.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 4434009..b662aed 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,12 @@
+2004-11-15 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
+	* memory.c: (zerror) Use zlog_err instead of fprintf to stderr.
+	  Instead of exiting, log currenty memory usage and then abort.
+	  (log_memstats) New function to log memory statistics, called by
+	  zerror.
+	  (show_memory_all) Loop over new mlists array instead of calling
+	  show_memory_vty separately for each memory_list.
+
 2004-11-08 Paul Jakma <paul@dishone.st>
 
 	* buffer.c: Add missing include of log.h.
diff --git a/lib/memory.c b/lib/memory.c
index bef0997..1f52bdf 100644
--- a/lib/memory.c
+++ b/lib/memory.c
@@ -27,6 +27,7 @@
 
 void alloc_inc (int);
 void alloc_dec (int);
+static void log_memstats(int log_priority);
 
 struct message mstr [] =
 {
@@ -42,9 +43,10 @@
 static void
 zerror (const char *fname, int type, size_t size)
 {
-  fprintf (stderr, "%s : can't allocate memory for `%s' size %d\n", 
-	   fname, lookup (mstr, type), (int) size);
-  exit (1);
+  zlog_err ("%s : can't allocate memory for `%s' size %d: %s\n", 
+	    fname, lookup (mstr, type), (int) size, strerror(errno));
+  log_memstats(LOG_WARNING);
+  abort();
 }
 
 /* Memory allocation. */
@@ -406,6 +408,36 @@
   { -1, NULL },
 };
 
+static struct mlist {
+  struct memory_list *list;
+  const char *name;
+} mlists[] = {
+  { memory_list_lib,   "LIB"},
+  { memory_list_rip,   "RIP"},
+  { memory_list_ripng, "RIPNG"},
+  { memory_list_ospf,  "OSPF"},
+  { memory_list_ospf6, "OSPF6"},
+  { memory_list_isis,  "ISIS"},
+  { memory_list_bgp,   "BGP"},
+  { NULL, NULL},
+};
+
+static void
+log_memstats(int pri)
+{
+  struct mlist *ml;
+
+  for (ml = mlists; ml->list; ml++)
+    {
+      struct memory_list *m;
+
+      zlog (NULL, pri, "Memory utilization in module %s:", ml->name);
+      for (m = ml->list; m->index >= 0; m++)
+	if (m->index && mstat[m->index].alloc)
+	  zlog (NULL, pri, "  %-22s: %5ld", m->format, mstat[m->index].alloc);
+    }
+}
+
 struct memory_list memory_list_separator[] =
 {
   { 0, NULL},
@@ -431,19 +463,14 @@
        "Memory statistics\n"
        "All memory statistics\n")
 {
-  show_memory_vty (vty, memory_list_lib);
-  show_memory_vty (vty, memory_list_separator);
-  show_memory_vty (vty, memory_list_rip);
-  show_memory_vty (vty, memory_list_separator);
-  show_memory_vty (vty, memory_list_ripng);
-  show_memory_vty (vty, memory_list_separator);
-  show_memory_vty (vty, memory_list_ospf);
-  show_memory_vty (vty, memory_list_separator);
-  show_memory_vty (vty, memory_list_ospf6);
-  show_memory_vty (vty, memory_list_separator);
-  show_memory_vty (vty, memory_list_isis);
-  show_memory_vty (vty, memory_list_separator);
-  show_memory_vty (vty, memory_list_bgp);
+  struct mlist *ml;
+
+  for (ml = mlists; ml->list; ml++)
+    {
+      if (ml != mlists)
+        show_memory_vty (vty, memory_list_separator);
+      show_memory_vty (vty, ml->list);
+    }
 
   return CMD_SUCCESS;
 }