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

	* log.c: (vzlog) Take a single va_list argument and use va_copy
	  as necessary for multiple traversals.
	  (zlog) Pass only one va_list to vzlog.
	  (zlog_*,plog_*) Use a macro for boilerplate code; pass only one
	  va_list to vzlog.
	  (zlog_set_file) Remove unused 2nd argument (flags).
	  (zlog_save_cwd,zlog_get_cwd,zlog_free_cwd) Remove unused functions.
	* log.h: Remove ZLOG_*_INDEX defines (no longer used).
	  Remove unused 2nd argument from zlog_set_file prototype.
	  Fix prototype for zlog_rotate.
	* command.c: (config_log_file) Remove unused 2nd arg to zlog_set_file.
	* vty.c: (vty_out) Fix stdarg usage to perform multiple traversals
	  properly.
	  (vty_log) Must use va_copy for multiple traversals of va_list arg.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 75cf844..f768088 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,20 @@
+2004-11-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
+	* log.c: (vzlog) Take a single va_list argument and use va_copy
+	  as necessary for multiple traversals.
+	  (zlog) Pass only one va_list to vzlog.
+	  (zlog_*,plog_*) Use a macro for boilerplate code; pass only one
+	  va_list to vzlog.
+	  (zlog_set_file) Remove unused 2nd argument (flags).
+	  (zlog_save_cwd,zlog_get_cwd,zlog_free_cwd) Remove unused functions.
+	* log.h: Remove ZLOG_*_INDEX defines (no longer used).
+	  Remove unused 2nd argument from zlog_set_file prototype.
+	  Fix prototype for zlog_rotate.
+	* command.c: (config_log_file) Remove unused 2nd arg to zlog_set_file.
+	* vty.c: (vty_out) Fix stdarg usage to perform multiple traversals
+	  properly.
+	  (vty_log) Must use va_copy for multiple traversals of va_list arg.
+
 2004-11-19 David Young <dyoung@pobox.com>
 
 	* log.c: (safe_strerror) New function: safe wrapper for strerror.
diff --git a/lib/command.c b/lib/command.c
index 6c02c96..60b0124 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -3017,7 +3017,7 @@
   else
     fullpath = argv[0];
 
-  ret = zlog_set_file (NULL, ZLOG_FILE, fullpath);
+  ret = zlog_set_file (NULL, fullpath);
 
   if (p)
     XFREE (MTYPE_TMP, p);
diff --git a/lib/log.c b/lib/log.c
index b24dacd..205b7c0 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -81,8 +81,8 @@
 }
 
 /* va_list version of zlog. */
-void
-vzlog (struct zlog *zl, int priority, const char *format, va_list *args)
+static void
+vzlog (struct zlog *zl, int priority, const char *format, va_list args)
 {
   /* If zlog is not specified, use default one. */
   if (zl == NULL)
@@ -93,7 +93,7 @@
     {
       time_print (stderr);
       fprintf (stderr, "%s: ", "unknown");
-      vfprintf (stderr, format, args[ZLOG_NOLOG_INDEX]);
+      vfprintf (stderr, format, args);
       fprintf (stderr, "\n");
       fflush (stderr);
 
@@ -107,16 +107,24 @@
 		
   /* Syslog output */
   if (zl->flags & ZLOG_SYSLOG)
-    vsyslog (priority|zlog_default->facility, format, args[ZLOG_SYSLOG_INDEX]);
+    {
+      va_list ac;
+      va_copy(ac, args);
+      vsyslog (priority|zlog_default->facility, format, ac);
+      va_end(ac);
+    }
 
   /* File output. */
   if (zl->flags & ZLOG_FILE)
     {
+      va_list ac;
       time_print (zl->fp);
       if (zl->record_priority)
 	fprintf (zl->fp, "%s: ", zlog_priority[priority]);
       fprintf (zl->fp, "%s: ", zlog_proto_names[zl->protocol]);
-      vfprintf (zl->fp, format, args[ZLOG_FILE_INDEX]);
+      va_copy(ac, args);
+      vfprintf (zl->fp, format, ac);
+      va_end(ac);
       fprintf (zl->fp, "\n");
       fflush (zl->fp);
     }
@@ -124,11 +132,14 @@
   /* stdout output. */
   if (zl->flags & ZLOG_STDOUT)
     {
+      va_list ac;
       time_print (stdout);
       if (zl->record_priority)
 	fprintf (stdout, "%s: ", zlog_priority[priority]);
       fprintf (stdout, "%s: ", zlog_proto_names[zl->protocol]);
-      vfprintf (stdout, format, args[ZLOG_STDOUT_INDEX]);
+      va_copy(ac, args);
+      vfprintf (stdout, format, ac);
+      va_end(ac);
       fprintf (stdout, "\n");
       fflush (stdout);
     }
@@ -136,183 +147,75 @@
   /* stderr output. */
   if (zl->flags & ZLOG_STDERR)
     {
+      va_list ac;
       time_print (stderr);
       if (zl->record_priority)
 	fprintf (stderr, "%s: ", zlog_priority[priority]);
       fprintf (stderr, "%s: ", zlog_proto_names[zl->protocol]);
-      vfprintf (stderr, format, args[ZLOG_STDERR_INDEX]);
+      va_copy(ac, args);
+      vfprintf (stderr, format, ac);
+      va_end(ac);
       fprintf (stderr, "\n");
       fflush (stderr);
     }
 
   /* Terminal monitor. */
-  vty_log (zlog_proto_names[zl->protocol], format, args[ZLOG_NOLOG_INDEX]);
+  vty_log (zlog_proto_names[zl->protocol], format, args);
 }
 
 void
 zlog (struct zlog *zl, int priority, const char *format, ...)
 {
-  va_list args[ZLOG_MAX_INDEX];
-  int index;
+  va_list args;
 
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_start(args[index], format);
-
+  va_start(args, format);
   vzlog (zl, priority, format, args);
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_end (args[index]);
+  va_end (args);
 }
 
-void
-zlog_err (const char *format, ...)
-{
-  va_list args[ZLOG_MAX_INDEX];
-  int index;
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_start(args[index], format);
-
-  vzlog (NULL, LOG_ERR, format, args);
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_end (args[index]);
+#define ZLOG_FUNC(FUNCNAME,PRIORITY) \
+void \
+FUNCNAME(const char *format, ...) \
+{ \
+  va_list args; \
+  va_start(args, format); \
+  vzlog (NULL, PRIORITY, format, args); \
+  va_end(args); \
 }
 
-void
-zlog_warn (const char *format, ...)
-{
-  va_list args[ZLOG_MAX_INDEX];
-  int index;
+ZLOG_FUNC(zlog_err, LOG_ERR)
 
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_start(args[index], format);
+ZLOG_FUNC(zlog_warn, LOG_WARNING)
 
-  vzlog (NULL, LOG_WARNING, format, args);
+ZLOG_FUNC(zlog_info, LOG_INFO)
 
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_end (args[index]);
+ZLOG_FUNC(zlog_notice, LOG_NOTICE)
+
+ZLOG_FUNC(zlog_debug, LOG_DEBUG)
+
+#undef ZLOG_FUNC
+
+#define PLOG_FUNC(FUNCNAME,PRIORITY) \
+void \
+FUNCNAME(struct zlog *zl, const char *format, ...) \
+{ \
+  va_list args; \
+  va_start(args, format); \
+  vzlog (zl, PRIORITY, format, args); \
+  va_end(args); \
 }
 
-void
-zlog_info (const char *format, ...)
-{
-  va_list args[ZLOG_MAX_INDEX];
-  int index;
+PLOG_FUNC(plog_err, LOG_ERR)
 
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_start(args[index], format);
+PLOG_FUNC(plog_warn, LOG_WARNING)
 
-  vzlog (NULL, LOG_INFO, format, args);
+PLOG_FUNC(plog_info, LOG_INFO)
 
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_end (args[index]);
-}
+PLOG_FUNC(plog_notice, LOG_NOTICE)
 
-void
-zlog_notice (const char *format, ...)
-{
-  va_list args[ZLOG_MAX_INDEX];
-  int index;
+PLOG_FUNC(plog_debug, LOG_DEBUG)
 
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_start(args[index], format);
-
-  vzlog (NULL, LOG_NOTICE, format, args);
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_end (args[index]);
-}
-
-void
-zlog_debug (const char *format, ...)
-{
-  va_list args[ZLOG_MAX_INDEX];
-  int index;
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_start(args[index], format);
-
-  vzlog (NULL, LOG_DEBUG, format, args);
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_end (args[index]);
-}
-
-void
-plog_err (struct zlog *zl, const char *format, ...)
-{
-  va_list args[ZLOG_MAX_INDEX];
-  int index;
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_start(args[index], format);
-
-  vzlog (zl, LOG_ERR, format, args);
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_end (args[index]);
-}
-
-void
-plog_warn (struct zlog *zl, const char *format, ...)
-{
-  va_list args[ZLOG_MAX_INDEX];
-  int index;
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_start(args[index], format);
-
-  vzlog (zl, LOG_WARNING, format, args);
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_end (args[index]);
-}
-
-void
-plog_info (struct zlog *zl, const char *format, ...)
-{
-  va_list args[ZLOG_MAX_INDEX];
-  int index;
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_start(args[index], format);
-
-  vzlog (zl, LOG_INFO, format, args);
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_end (args[index]);
-}
-
-void
-plog_notice (struct zlog *zl, const char *format, ...)
-{
-  va_list args[ZLOG_MAX_INDEX];
-  int index;
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_start(args[index], format);
-
-  vzlog (zl, LOG_NOTICE, format, args);
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_end (args[index]);
-}
-
-void
-plog_debug (struct zlog *zl, const char *format, ...)
-{
-  va_list args[ZLOG_MAX_INDEX];
-  int index;
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_start(args[index], format);
-
-  vzlog (zl, LOG_DEBUG, format, args);
-
-  for (index = 0; index < ZLOG_MAX_INDEX; index++)
-    va_end (args[index]);
-}
+#undef PLOG_FUNC
 
 
 /* Open log stream */
@@ -366,7 +269,7 @@
 }
 
 int
-zlog_set_file (struct zlog *zl, int flags, const char *filename)
+zlog_set_file (struct zlog *zl, const char *filename)
 {
   FILE *fp;
   mode_t oldumask;
@@ -447,32 +350,6 @@
   return 1;
 }
 
-static char *zlog_cwd = NULL;
-
-void
-zlog_save_cwd ()
-{
-  char *cwd;
-
-  cwd = getcwd (NULL, MAXPATHLEN);
-
-  zlog_cwd = XMALLOC (MTYPE_TMP, strlen (cwd) + 1);
-  strcpy (zlog_cwd, cwd);
-}
-
-char *
-zlog_get_cwd ()
-{
-  return zlog_cwd;
-}
-
-void
-zlog_free_cwd ()
-{
-  if (zlog_cwd)
-    XFREE (MTYPE_TMP, zlog_cwd);
-}
-
 /* Message lookup function. */
 const char *
 lookup (struct message *mes, int key)
diff --git a/lib/log.h b/lib/log.h
index b5dbdfe..e043760 100644
--- a/lib/log.h
+++ b/lib/log.h
@@ -30,13 +30,6 @@
 #define ZLOG_STDOUT             0x04
 #define ZLOG_STDERR             0x08
 
-#define ZLOG_NOLOG_INDEX        0
-#define ZLOG_FILE_INDEX         1
-#define ZLOG_SYSLOG_INDEX       2
-#define ZLOG_STDOUT_INDEX       3
-#define ZLOG_STDERR_INDEX       4
-#define ZLOG_MAX_INDEX          5
-
 typedef enum 
 {
   ZLOG_NONE,
@@ -112,11 +105,11 @@
 void zlog_reset_flag (struct zlog *zl, int flags);
 
 /* Set zlog filename. */
-int zlog_set_file (struct zlog *zl, int flags, const char *filename);
+int zlog_set_file (struct zlog *zl, const char *filename);
 int zlog_reset_file (struct zlog *zl);
 
 /* Rotate log. */
-int zlog_rotate ();
+int zlog_rotate (struct zlog *);
 
 /* For hackey massage lookup and check */
 #define LOOKUP(x, y) mes_lookup(x, x ## _max, y)
diff --git a/lib/vty.c b/lib/vty.c
index 016e52a..2f3bac2 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -95,21 +95,27 @@
   int size = 1024;
   char buf[1024];
   char *p = NULL;
-  
-  va_start (args, format);
 
   if (vty_shell (vty))
-    vprintf (format, args);
+    {
+      va_start (args, format);
+      vprintf (format, args);
+      va_end (args);
+    }
   else
     {
       /* Try to write to initial buffer.  */
+      va_start (args, format);
       len = vsnprintf (buf, sizeof buf, format, args);
+      va_end (args);
 
       /* Initial buffer is not enough.  */
       if (len < 0 || len >= size)
 	{
 	  while (1)
 	    {
+	      va_list ac;
+
 	      if (len > -1)
 		size = len + 1;
 	      else
@@ -119,7 +125,9 @@
 	      if (! p)
 		return -1;
 
+	      va_start (args, format);
 	      len = vsnprintf (p, size, format, args);
+	      va_end (args);
 
 	      if (len > -1 && len < size)
 		break;
@@ -138,12 +146,10 @@
 	XFREE (MTYPE_VTY_OUT_BUF, p);
     }
 
-  va_end (args);
-
   return len;
 }
 
-int
+static int
 vty_log_out (struct vty *vty, const char *proto_str, const char *format,
 	     va_list va)
 {
@@ -2277,7 +2283,12 @@
   for (i = 0; i < vector_max (vtyvec); i++)
     if ((vty = vector_slot (vtyvec, i)) != NULL)
       if (vty->monitor)
-	vty_log_out (vty, proto_str, format, va);
+	{
+	  va_list ac;
+	  va_copy(ac, va);
+	  vty_log_out (vty, proto_str, format, ac);
+	  va_end(ac);
+	}
 }
 
 int