diff --git a/configure b/configure
index 2f23a414ecfe37945277a38fbf07d5cd236c4b74..1aa749cd075a32394177c0d37753609a33c53008 100755
--- a/configure
+++ b/configure
@@ -1520,7 +1520,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
 	tbsetup/rmgroup tbsetup/webrmuser tbsetup/webrmgroup tbsetup/mkexpdir \
 	tbsetup/webnodecontrol tbsetup/node_control \
         tbsetup/webmkgroup tbsetup/mkgroup tbsetup/eventsys_start \
-	tbsetup/eventsys_control \
+	tbsetup/eventsys_control tbsetup/webevensys_control \
 	tbsetup/webmkproj tbsetup/mkproj tbsetup/libtestbed.pm \
 	tbsetup/portstats tbsetup/vnode_setup tbsetup/staticroutes \
 	tbsetup/console_setup.proxy tbsetup/exports_setup.proxy \
diff --git a/configure.in b/configure.in
index 899e6f5e2e768ef37a12a66c42ae809fe62a2306..b02d15b9ee5c594ba008fc855d9613bf4eac35b2 100755
--- a/configure.in
+++ b/configure.in
@@ -550,7 +550,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
 	tbsetup/rmgroup tbsetup/webrmuser tbsetup/webrmgroup tbsetup/mkexpdir \
 	tbsetup/webnodecontrol tbsetup/node_control \
         tbsetup/webmkgroup tbsetup/mkgroup tbsetup/eventsys_start \
-	tbsetup/eventsys_control \
+	tbsetup/eventsys_control tbsetup/webevensys_control \
 	tbsetup/webmkproj tbsetup/mkproj tbsetup/libtestbed.pm \
 	tbsetup/portstats tbsetup/vnode_setup tbsetup/staticroutes \
 	tbsetup/console_setup.proxy tbsetup/exports_setup.proxy \
diff --git a/tbsetup/GNUmakefile.in b/tbsetup/GNUmakefile.in
index 4085da3be34e66a582792688d15d75fcba77f403..460c770b031765459a23556c867a0834f0b658d6 100644
--- a/tbsetup/GNUmakefile.in
+++ b/tbsetup/GNUmakefile.in
@@ -38,7 +38,7 @@ LIBEXEC_STUFF	= rmproj wanlinksolve wanlinkinfo \
 		  webendexp webbatchexp webpanic \
 		  assign_wrapper assign_prepass ptopgen webnodeupdate \
 		  webdelay_config \
-		  webrmgroup webswapexp webnodecontrol \
+		  webrmgroup webswapexp webnodecontrol webeventsys_control \
 		  webmkgroup websetgroups webmkproj \
 		  spewlogfile staticroutes routecalc wanassign \
 		  webnodereboot webrmuser webidleswap switchmac \
diff --git a/tbsetup/webeventsys_control.in b/tbsetup/webeventsys_control.in
new file mode 100644
index 0000000000000000000000000000000000000000..ff936f3fad1554d755a47d5061c95a28cff9fdbd
--- /dev/null
+++ b/tbsetup/webeventsys_control.in
@@ -0,0 +1,27 @@
+#!/usr/bin/perl -w
+
+#
+# EMULAB-COPYRIGHT
+# Copyright (c) 2004 University of Utah and the Flux Group.
+# All rights reserved.
+#
+
+use English;
+
+#
+# This gets invoked from the Web interface. Simply a wrapper ...
+#
+# usage: webeventsys_control arguments ...
+#
+
+#
+# Configure variables
+#
+my $TB       = "@prefix@";
+
+#
+# Run the real thing, and never return.
+# 
+exec "$TB/bin/eventsys_control", @ARGV;
+
+die("webeventsys_control: Could not exec swapexp: $!");
diff --git a/www/replayexp.php3 b/www/replayexp.php3
new file mode 100644
index 0000000000000000000000000000000000000000..63a4c07728209b62f1f15e6bc0511040add933ca
--- /dev/null
+++ b/www/replayexp.php3
@@ -0,0 +1,121 @@
+<?php
+#
+# EMULAB-COPYRIGHT
+# Copyright (c) 2000-2004 University of Utah and the Flux Group.
+# All rights reserved.
+#
+include("defs.php3");
+include("showstuff.php3");
+
+#
+# Only known and logged in users can end experiments.
+#
+$uid = GETLOGIN();
+LOGGEDINORDIE($uid);
+
+#
+# Must provide the EID!
+# 
+if (!isset($pid) ||
+    strcmp($pid, "") == 0) {
+    USERERROR("The project ID was not provided!", 1);
+}
+
+if (!isset($eid) ||
+    strcmp($eid, "") == 0) {
+    USERERROR("The experiment ID was not provided!", 1);
+}
+
+# Canceled operation redirects back to showexp page. See below.
+if ($canceled) {
+    header("Location: showexp.php3?pid=$pid&eid=$eid");
+    return;
+}
+
+#
+# Standard Testbed Header, after cancel above.
+#
+PAGEHEADER("Replay Control");
+
+$exp_eid = $eid;
+$exp_pid = $pid;
+
+#
+# Check to make sure thats this is a valid PID/EID tuple.
+#
+$query_result =
+    DBQueryFatal("SELECT * FROM experiments WHERE ".
+		 "eid='$exp_eid' and pid='$exp_pid'");
+if (mysql_num_rows($query_result) == 0) {
+    USERERROR("The experiment $exp_eid is not a valid experiment ".
+	      "in project $exp_pid.", 1);
+}
+$row           = mysql_fetch_array($query_result);
+$exp_gid       = $row[gid];
+
+#
+# Verify permissions.
+#
+if (! TBExptAccessCheck($uid, $exp_pid, $exp_eid, $TB_EXPT_MODIFY)) {
+    USERERROR("You do not have permission for $exp_eid!", 1);
+}
+
+echo "<font size=+2>Experiment <b>".
+     "<a href='showproject.php3?pid=$pid'>$pid</a>/".
+     "<a href='showexp.php3?pid=$pid&eid=$eid'>$eid</a></b></font><br>\n";
+
+#
+# We run this twice. The first time we are checking for a confirmation
+# by putting up a form. The next time through the confirmation will be
+# set. Or, the user can hit the cancel button, in which case we 
+# redirect the browser back to the experiment page (see above).
+#
+if (!$confirmed) {
+    echo "<center><h2><br>
+          Are you sure you want to replay all events in experiment '$exp_eid?'
+          </h2>\n";
+    
+    SHOWEXP($exp_pid, $exp_eid, 1);
+
+    echo "<form action='replayexp.php3?pid=$exp_pid&eid=$exp_eid'
+                method=post>";
+
+    echo "<b><input type=submit name=confirmed value=Confirm></b>\n";
+    echo "<b><input type=submit name=canceled value=Cancel></b>\n";
+    echo "</form>\n";
+
+    PAGEFOOTER();
+    return;
+}
+
+#
+# We need the unix gid for the project for running the scripts below.
+# Note usage of default group in project.
+#
+TBGroupUnixInfo($exp_pid, $exp_gid, $unix_gid, $unix_name);
+
+#
+# We run a wrapper script that does all the work of restarting the events
+#
+echo "<center>";
+echo "<h2>Starting event replay. Please wait a moment ...
+      </h2></center>";
+
+flush();
+
+#
+# Avoid SIGPROF in child.
+# 
+set_time_limit(0);
+
+$retval = SUEXEC($uid, "$exp_pid,$unix_gid",
+		  "webeventsys_control replay $exp_pid $exp_eid",
+		 SUEXEC_ACTION_DIE);
+
+echo "Events for your experiment are now being replayed.\n";
+
+#
+# Standard Testbed Footer
+# 
+PAGEFOOTER();
+?>
diff --git a/www/showexp.php3 b/www/showexp.php3
index 8c0ac4aa9cb08f5f3aa205b6d806a4d92bc0da72..53f33829c2c30595a78046e7af56d7a93c4fd45f 100644
--- a/www/showexp.php3
+++ b/www/showexp.php3
@@ -227,6 +227,8 @@ if ($isadmin) {
 	WRITESUBMENUBUTTON("Restart Experiment",
 			   "swapexp.php3?inout=restart&pid=$exp_pid".
 			   "&eid=$exp_eid");
+	WRITESUBMENUBUTTON("Replay Events",
+			   "replayexp.php3?&pid=$exp_pid&eid=$exp_eid");
 
 	SUBMENUSECTION("Admin Options");