summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authoreea1 <eea1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-08-24 23:12:37 +0000
committereea1 <eea1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-08-24 23:12:37 +0000
commit2277d3e8270d04092497d70fa24250bae88211a4 (patch)
treeec567c584c3d5aa77cc2ca9340c9680a45b3a66a /java
parent65e8b604882f17ee2f0010b5c8e43d88b0164b3b (diff)
downloadATCD-2277d3e8270d04092497d70fa24250bae88211a4.tar.gz
Updated source files for netsvcs/Time.
Diffstat (limited to 'java')
-rw-r--r--java/JACE/netsvcs/Time/TSClerkHandler.java195
-rw-r--r--java/JACE/netsvcs/Time/TSClerkProcessor.java307
-rw-r--r--java/JACE/netsvcs/Time/TSServerAcceptor.java116
-rw-r--r--java/JACE/netsvcs/Time/TSServerHandler.java53
-rw-r--r--java/JACE/netsvcs/Time/TimeInfo.java90
-rw-r--r--java/JACE/netsvcs/Time/TimeRequest.java121
-rw-r--r--java/JACE/netsvcs/Time/c.bat1
-rw-r--r--java/JACE/netsvcs/Time/package.html10
-rw-r--r--java/JACE/netsvcs/Time/r.bat1
9 files changed, 894 insertions, 0 deletions
diff --git a/java/JACE/netsvcs/Time/TSClerkHandler.java b/java/JACE/netsvcs/Time/TSClerkHandler.java
new file mode 100644
index 00000000000..e0a2290d81b
--- /dev/null
+++ b/java/JACE/netsvcs/Time/TSClerkHandler.java
@@ -0,0 +1,195 @@
+package JACE.netsvcs.Time;
+
+import java.io.*;
+import java.net.*;
+
+import JACE.OS.*;
+import JACE.Connection.*;
+import JACE.ASX.*;
+
+/**
+ * Requests a time update from a time server. This is used by the
+ * TSClerkProcessor to query a server.
+ */
+public class TSClerkHandler extends SvcHandler
+{
+ /**
+ * Constructor.
+ *
+ *@param parent TSClerkProcessor which is creating this instance
+ *@param host name of the machine this handler is connected to
+ *@param port port on the time server to connect to
+ */
+ public TSClerkHandler (TSClerkProcessor parent,
+ String host,
+ int port)
+ {
+ parent_ = parent;
+ host_ = host;
+ port_ = port;
+ }
+
+ /**
+ * Initialize this handler. Called automatically by Connector when a
+ * successful connection is made.
+ *
+ *@return -1 on failure, 0 on success
+ */
+ public int open (Object obj)
+ {
+ ACE.DEBUG ("Successful connection to " + host ());
+ connected (true);
+ return 0;
+ }
+
+ /**
+ * Safely shut down this handler, closing the socket.
+ *
+ *@return -1 on failure, 0 on success
+ */
+ public synchronized int close ()
+ {
+ if (!connected ())
+ return 0;
+
+ ACE.DEBUG ("Shutting down connection to " + host ());
+ try {
+ peer ().close ();
+ } catch (IOException e) {
+ return -1;
+ } finally {
+ connected (false);
+ }
+
+ return 0;
+ }
+
+ /**
+ * Accessor for the port number of the server.
+ */
+ public int port ()
+ {
+ return port_;
+ }
+
+ /**
+ * Accessor for the host name of the server.
+ */
+ public String host ()
+ {
+ return host_;
+ }
+
+ /**
+ * Check to see if this handler is currently connected to a server.
+ */
+ public synchronized boolean connected ()
+ {
+ return connected_;
+ }
+
+ /**
+ * Set the connected state.
+ *
+ *@param state true if connected, false if not
+ */
+ protected synchronized void connected (boolean state)
+ {
+ connected_ = state;
+ }
+
+ /**
+ * (Isn't used, just fulfills the interface. Returns -1 by
+ * default)
+ */
+ public int handleTimeout (TimeValue tv, Object obj)
+ {
+ return -1;
+ }
+
+ /**
+ * (Isn't used, just fulfills the interface.)
+ */
+ public void run ()
+ {
+ ACE.ERROR ("TSClerkHandler is not setup to run in its own thread");
+ }
+
+ /**
+ * Sends a request to the server and waits for a reply. This is called
+ * by TSClerkProcessor.
+ *
+ *@return -1 on failure, 0 on success
+ */
+ public int sendRequest ()
+ {
+ // Ask the clerk processor to connect this handler if it isn't
+ // already. Thus, it tries to reconnect if the server has gone
+ // down.
+ if (!connected ())
+ parent_.connectHandler (this, host_, port_);
+
+ TimeRequest request = new TimeRequest ();
+
+ long start, stop;
+ try {
+
+ start = System.currentTimeMillis ();
+ request.streamOutTo (peer().outputStream ());
+
+ request.streamInFrom (peer().inputStream ());
+ stop = System.currentTimeMillis ();
+
+ } catch (NullPointerException e) {
+ close ();
+ return -1;
+ } catch (IOException e) {
+ close ();
+ return -1;
+ }
+
+ // Compute the difference in the local time and the server time
+ // (in seconds)
+ long difference = request.time () - (stop / 1000);
+
+ // Calculate the transmission time (in seconds)
+ long oneWayTime = (stop - start) / 2000;
+
+ difference += oneWayTime;
+
+ /*
+ ACE.DEBUG (host() + " reports:");
+ ACE.DEBUG (" time difference: " + difference);
+ ACE.DEBUG (" trans. delay: " + oneWayTime);
+ */
+
+ // Set the time difference for this handler
+ delta (difference);
+
+ return 0;
+ }
+
+ /**
+ * Returns the current time difference between local time and
+ * the server (in seconds).
+ */
+ public synchronized long delta ()
+ {
+ return delta_;
+ }
+
+ /**
+ * Sets the current time difference between local time and the
+ * server (in seconds).
+ */
+ protected synchronized void delta (long delta)
+ {
+ delta_ = delta;
+ }
+
+ private long delta_;
+ private TSClerkProcessor parent_;
+ private boolean connected_ = false;
+ private String host_;
+ private int port_;
+}
diff --git a/java/JACE/netsvcs/Time/TSClerkProcessor.java b/java/JACE/netsvcs/Time/TSClerkProcessor.java
new file mode 100644
index 00000000000..bec3bd417df
--- /dev/null
+++ b/java/JACE/netsvcs/Time/TSClerkProcessor.java
@@ -0,0 +1,307 @@
+package JACE.netsvcs.Time;
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+
+import JACE.ASX.TimeValue;
+import JACE.Connection.*;
+import JACE.OS.*;
+import JACE.Reactor.*;
+import JACE.Misc.*;
+
+/**
+ * Clerk used to query a number of time servers, compute the average
+ * of the time differences, and report it with a sequence number. This
+ * can be used to adjust the current local time accordingly.
+ * <P>
+ * <B>Valid command line arguments:</B>
+ * <PRE>
+ * -h (host name:port) Specify a time server to contact
+ * -t (time in seconds) Specify how often to query the servers
+ * (Defaults to five minutes)
+ * -d Enable debugging messages
+ * </PRE>
+ */
+public class TSClerkProcessor implements EventHandler, Runnable
+{
+ /**
+ * Prints out the valid command line arguments. See the class
+ * description for more information.
+ */
+ public void printUsage ()
+ {
+ ACE.ERROR ("Valid options:");
+ ACE.ERROR ("-h <host name>:<port> Specify a time server to contact");
+ ACE.ERROR ("-t <time in seconds> How often to query the servers");
+ ACE.ERROR ("-d Enable debugging messages");
+ }
+
+ /**
+ * Parses the command line arguments. See the class description
+ * for more information.
+ */
+ protected int parseArgs (String args[])
+ {
+ GetOpt opt = new GetOpt (args, "h:t:d", true);
+ for (int c; (c = opt.next ()) != -1; )
+ {
+ switch (c)
+ {
+ // Specify a hostname:port pair to query
+ case 'h':
+ if (newHandler (opt.optarg ()) == -1) {
+ printUsage ();
+ return -1;
+ }
+ break;
+ // Specify time interval to query servers
+ case 't':
+ int sec = Integer.parseInt (opt.optarg ());
+ updateInterval_ = new TimeValue (sec);
+ break;
+ case 'd':
+ ACE.enableDebugging ();
+ ACE.DEBUG ("Debugging is enabled");
+ break;
+ default:
+ ACE.ERROR ("Unknown argument: " + (char)c);
+ printUsage ();
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Safely shut down the clerk and all its handlers.
+ */
+ public synchronized void close ()
+ {
+ if (!done_) {
+ done_ = true;
+ tq_.cancelTimer (this);
+
+ for (int i = 0; i < handlerSet_.size (); i++) {
+ TSClerkHandler h = (TSClerkHandler)handlerSet_.elementAt (i);
+
+ h.close ();
+ }
+ }
+ }
+
+ /**
+ * Called by the JVM when the clerk is run in its own thread. If the
+ * TimerQueue provided to (or created by) this TSClerkProcessor isn't
+ * running its event loop, it will be run in this thread (by calling
+ * handleEvents ()).
+ *
+ *@see JACE.Reactor.TimerQueue
+ */
+ public void run ()
+ {
+ if (handlerSet_.size () == 0) {
+ ACE.DEBUG ("No servers are registered. Call init first.");
+ return;
+ }
+
+ if (!tq_.eventLoopRunning ())
+ tq_.handleEvents ();
+ }
+
+ /**
+ * Initialize this TSClerkProcessor with command line arguments. See
+ * the class description for more information. This also schedules
+ * a timeout with the timer queue for when to query the servers.
+ *
+ *@return -1 on failure, 0 on success
+ */
+ public int init (String args[])
+ {
+ if (args.length < 2) {
+ printUsage ();
+ return -1;
+ }
+
+ if (parseArgs (args) == -1)
+ return -1;
+
+ if (handlerSet_.size () == 0) {
+ ACE.ERROR ("No servers are registered.");
+ done_ = true;
+ return -1;
+ }
+
+ if (tq_ == null)
+ tq_ = new TimerQueue (true);
+
+ tq_.scheduleTimer (this,
+ "Time Service Processor",
+ TimeValue.zero,
+ updateInterval_);
+
+ return 0;
+ }
+
+ /**
+ * Called by TSClerkHandler instances when they need to connect
+ * (or reconnect) to a server. This uses Connector to make the
+ * connection.
+ *
+ *@param handler TSClerkHandler to connect to the server
+ *@param host name of the service
+ *@param port port to connect to on the server
+ */
+ void connectHandler (TSClerkHandler handler,
+ String host,
+ int port)
+ {
+ // Don't let handlers reconnect if we are in the process of closing
+ if (done_)
+ return;
+
+ ACE.DEBUG ("Connecting handler to " + host + " on port " + port);
+ try {
+
+ Connector c = new Connector ();
+ c.open (host, port);
+ c.connect (handler);
+
+ } catch (UnknownHostException e) {
+ synchronized (this) {
+ handlerSet_.removeElement (handler);
+ }
+ ACE.ERROR (e);
+ } catch (SocketException e) {
+ ACE.ERROR (e);
+ } catch (InstantiationException e) {
+ ACE.ERROR (e);
+ } catch (IllegalAccessException e) {
+ ACE.ERROR (e);
+ } catch (IOException e) {
+ ACE.ERROR (e);
+ }
+ }
+
+ /**
+ * Create a new TSClerkHandler for the given (host name):(port)
+ * combination. See the class description for more information about
+ * providing a host names and ports on the command line.
+ *
+ *@param hostAndPort String with the host name and port separated by
+ * a colon.
+ *@return -1 on failure, 0 on success
+ */
+ protected int newHandler (String hostAndPort)
+ {
+ int colon = hostAndPort.lastIndexOf (':');
+
+ if (colon < 1) {
+ ACE.ERROR ("Invalid -h <host>:<port> parameter: " + hostAndPort);
+ return -1;
+ }
+
+ int port = Integer.parseInt (hostAndPort.substring (colon + 1));
+ String host = hostAndPort.substring (0, colon);
+
+ ACE.DEBUG ("New handler for server " + host + " on port " + port);
+
+ TSClerkHandler handler = new TSClerkHandler (this, host, port);
+ handlerSet_.addElement (handler);
+
+ return 0;
+ }
+
+ /**
+ * Have each TSClerkHandler query its time server, average the results,
+ * and set the timeStatus accordingly. This is called by the
+ * TimerQueue when appropriate. The interval can be specified on the
+ * command line.
+ */
+ public synchronized int handleTimeout (TimeValue tv, Object obj)
+ {
+ if (done_)
+ return -1;
+
+ // Increment the sequence number
+ int sequenceNumber = status_.sequenceNumber () + 1;
+ Enumeration handlers = handlerSet_.elements ();
+
+ long total = 0;
+ int count = 0;
+
+ // Use each handler to query its server, collecting the time
+ // difference information.
+ while (handlers.hasMoreElements ()) {
+ TSClerkHandler h = (TSClerkHandler)handlers.nextElement ();
+
+ if (h.sendRequest () < 0)
+ continue;
+
+ total += h.delta ();
+ count++;
+ }
+
+ if (count == 0) {
+ ACE.ERROR ("Could not reach any time servers, will keep trying.");
+ return 0;
+ }
+
+ timeStatus (new TimeInfo (sequenceNumber, total / count));
+
+ ACE.DEBUG ("Status: " + timeStatus ());
+
+ return 0;
+ }
+
+ /**
+ * Return the current sequence number and time difference pair.
+ */
+ public synchronized TimeInfo timeStatus ()
+ {
+ return status_;
+ }
+
+ /**
+ * Set the current sequence number and time difference pair.
+ */
+ protected synchronized void timeStatus (TimeInfo status)
+ {
+ status_ = status;
+ }
+
+ /**
+ * Default constructor. Results in this TSClerkProcessor creating
+ * a new timer queue which runs in its own thread. Thus, this
+ * TSClerkProcessor runs in its own thread.
+ */
+ public TSClerkProcessor ()
+ {
+ // Effectively runs in its own thread because of the timer queue
+ }
+
+ /**
+ * Constructor allowing the timer queue to be specified. If the timer
+ * queue isn't already running, the caller is responsible for calling
+ * handleEvents to start the clerk. Be careful since the querying
+ * process for the servers may take a while.
+ *
+ *@param queue TimerQueue to register with
+ */
+ public TSClerkProcessor (TimerQueue queue)
+ {
+ tq_ = queue;
+ }
+
+ private boolean done_ = false;
+
+ // List of the TSClerkHandlers this uses to maintain its
+ // server connections.
+ private Vector handlerSet_ = new Vector ();
+ private TimerQueue tq_ = null;
+
+ // Default is every five minutes
+ private TimeValue updateInterval_ = new TimeValue (300, 0);
+
+ TimeInfo status_ = new TimeInfo ();
+}
diff --git a/java/JACE/netsvcs/Time/TSServerAcceptor.java b/java/JACE/netsvcs/Time/TSServerAcceptor.java
new file mode 100644
index 00000000000..7e8b9476c19
--- /dev/null
+++ b/java/JACE/netsvcs/Time/TSServerAcceptor.java
@@ -0,0 +1,116 @@
+package JACE.netsvcs.Time;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import JACE.OS.*;
+import JACE.Misc.*;
+import JACE.Connection.*;
+import JACE.Reactor.*;
+import JACE.ASX.TimeValue;
+import JACE.Concurrency.ThreadManager;
+import JACE.netsvcs.Server;
+
+/**
+ * Server for the time service. Creates TSServerHandlers as necessary
+ * to handle the requests.
+ * <P>
+ * <B>Valid command line arguments:</B>
+ * <PRE>
+ * -p (port) Port to listen on for clients");
+ * -d Enable debugging messages");
+ * -a (class name) Specify ActivateStrategy");
+ * (Default is multi-threaded");
+ * </PRE>
+ *
+ */
+public class TSServerAcceptor extends Server
+{
+ public TSServerAcceptor ()
+ {
+ // Set the name in case we're not using the service configurator
+ name ("Time Service");
+ }
+
+ /**
+ * Simple main program for running the logging service without the
+ * service configurator.
+ *
+ *@param args command line arguments
+ */
+ public static void main (String [] args)
+ {
+ // Simple main program to get things rolling
+ TSServerAcceptor ta = new TSServerAcceptor();
+
+ ta.init (args);
+ }
+
+ /**
+ * Creates a new TSServerHandler instance.
+ */
+ protected SvcHandler makeSvcHandler ()
+ {
+ return new TSServerHandler ();
+ }
+
+ /**
+ * Prints out the valid command line arguments. See the class
+ * description for more information. Called by Server.init when
+ * parseArgs returns -1.
+ */
+ protected void printUsage ()
+ {
+ ACE.ERROR ("Valid options:\n");
+ ACE.ERROR ("-p <port> Port to listen on for clients");
+ ACE.ERROR ("-d Enable debugging messages");
+ ACE.ERROR ("-a <class name> Specify ActivateStrategy");
+ ACE.ERROR (" (Default is multi-threaded");
+ }
+
+ /**
+ * Parses the command line arguments. See the class description
+ * for more information.
+ *
+ *@param args command line arguments
+ *@return -1 on failure, 0 on success
+ */
+ protected int parseArgs (String [] args)
+ {
+ int c = 0;
+ GetOpt opt = new GetOpt(args, "p:da:", true);
+
+ try {
+
+ while ((c = opt.next ()) != -1) {
+ switch (c)
+ {
+ case 'd':
+ ACE.enableDebugging ();
+ ACE.DEBUG ("Debugging is enabled");
+ break;
+ case 'p':
+ if (!port (opt.optarg ()))
+ return -1;
+ break;
+ case 'a':
+ Object strategy = newStrategyInstance (opt.optarg (),
+ "ActivateStrategy");
+ if (strategy == null)
+ return -1;
+
+ activateStrategy ((ActivateStrategy) strategy);
+ break;
+ default:
+ ACE.ERROR("Unknown argument: " + (char)c);
+ return -1;
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ ACE.ERROR ("Option -" + (char)c + " requires an argument");
+ return -1;
+ }
+
+ return 0;
+ }
+}
diff --git a/java/JACE/netsvcs/Time/TSServerHandler.java b/java/JACE/netsvcs/Time/TSServerHandler.java
new file mode 100644
index 00000000000..69bf4239280
--- /dev/null
+++ b/java/JACE/netsvcs/Time/TSServerHandler.java
@@ -0,0 +1,53 @@
+package JACE.netsvcs.Time;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import JACE.OS.*;
+import JACE.Connection.*;
+import JACE.Reactor.*;
+import JACE.SOCK_SAP.*;
+import JACE.netsvcs.Handler;
+
+/**
+ * Created by TSServerAcceptor to handle time update requests. Currently,
+ * this simply sends back the current time (in seconds).
+ *
+ * @see JACE.netsvcs.Logger.ServerLoggingAcceptor
+ */
+public class TSServerHandler extends Handler
+{
+ /**
+ * Reads in the given TimeRequest request and calls dispatch.
+ *
+ *@param request TimeRequest instance to use
+ */
+ public void processRequest (Object requestObject)
+ throws SocketException, EOFException, IOException
+ {
+ TimeRequest request = (TimeRequest)requestObject;
+
+ request.streamInFrom (peer ().dataInputStream ());
+
+ this.dispatch (request);
+ }
+
+ /**
+ * Sets the time value of the request to be the local time (in sec)
+ * and sends it back to the client.
+ */
+ void dispatch(TimeRequest request) throws IOException
+ {
+ request.time ((int)(System.currentTimeMillis () / 1000));
+
+ request.streamOutTo (peer().outputStream ());
+ }
+
+ /**
+ * Creates a new instance of TimeRequest.
+ */
+ public Object newRequest ()
+ {
+ return new TimeRequest ();
+ }
+}
diff --git a/java/JACE/netsvcs/Time/TimeInfo.java b/java/JACE/netsvcs/Time/TimeInfo.java
new file mode 100644
index 00000000000..4ebfc793adb
--- /dev/null
+++ b/java/JACE/netsvcs/Time/TimeInfo.java
@@ -0,0 +1,90 @@
+package JACE.netsvcs.Time;
+
+/**
+ * Wrapper for use with the clerk, containing a sequence number and
+ * time offset pair.
+ */
+public class TimeInfo
+{
+ /**
+ * Default constructor.
+ */
+ public TimeInfo ()
+ {
+ this (0, 0);
+ }
+
+ /**
+ * Constructor.
+ *
+ *@param seqNum sequence number
+ *@param delta time offset in seconds
+ */
+ public TimeInfo (int seqNum, long delta)
+ {
+ sequenceNumber_ = seqNum;
+ delta_ = delta;
+ }
+
+ /**
+ * Returns this TimeInfo's sequence number.
+ */
+ public int sequenceNumber ()
+ {
+ return sequenceNumber_;
+ }
+
+ /**
+ * Sets this TimeInfo's sequence number.
+ */
+ public void sequenceNumber (int num)
+ {
+ sequenceNumber_ = num;
+ }
+
+ /**
+ * Returns the time offset represented by this TimeInfo instance.
+ * (in sec)
+ */
+ public long delta ()
+ {
+ return delta_;
+ }
+
+ /**
+ * Sets the time offset (in sec).
+ */
+ public void delta (long num)
+ {
+ delta_ = num;
+ }
+
+ /**
+ * Returns an informative String about the time difference represented
+ * by this TimeInfo instance. The sequence number is included in
+ * brackets.
+ * <P>
+ * Example:
+ * <PRE>
+ * Local time is 3 sec slower [57]
+ * </PRE>
+ */
+ public String toString ()
+ {
+ String result = "Local time is ";
+ if (delta_ > 0) {
+ result += (delta_ + " sec slower");
+ } else
+ if (delta_ < 0) {
+ result += (delta_ + " sec faster");
+ } else
+ result += "the same as the average";
+
+ result += " [" + sequenceNumber_ + "]";
+
+ return result;
+ }
+
+ private long delta_;
+ private int sequenceNumber_;
+}
diff --git a/java/JACE/netsvcs/Time/TimeRequest.java b/java/JACE/netsvcs/Time/TimeRequest.java
new file mode 100644
index 00000000000..1b0e691398a
--- /dev/null
+++ b/java/JACE/netsvcs/Time/TimeRequest.java
@@ -0,0 +1,121 @@
+package JACE.netsvcs.Time;
+
+import java.io.*;
+import java.net.*;
+
+/**
+ * Request for a time update (and its reply). This is compatible with
+ * C++ ACE_Time_Request. Currently, the Java version always specifies to
+ * block forever for requests.
+ */
+public class TimeRequest
+{
+ /**
+ * Type for requesting updates.
+ */
+ public static int TIME_UPDATE = 01;
+
+ /**
+ * Default constructor, specifies block forever for an update.
+ */
+ public TimeRequest ()
+ {
+ messageType_ = TIME_UPDATE;
+ blockForever_ = 1;
+ }
+
+ /**
+ * Constructor specifying the type of request, the current
+ * time, and to block forever.
+ */
+ public TimeRequest (int messageType,
+ int timeSec)
+ {
+ time_ = timeSec;
+ messageType_ = messageType;
+ blockForever_ = 1;
+ }
+
+ /**
+ * Dump all class information to a String.
+ */
+ public String toString ()
+ {
+ return "TimeRequest (" + messageType_ +
+ ", " + blockForever_ + ", " + secTimeout_ + ", " +
+ usecTimeout_ + ", " + time_ + ")";
+ }
+
+ /**
+ * Read the TimeRequest in from a given InputStream.
+ */
+ public void streamInFrom (InputStream is)
+ throws IOException, EOFException
+ {
+ BufferedInputStream bis = new BufferedInputStream (is, 25);
+ DataInputStream dis = new DataInputStream (bis);
+
+ streamInFrom (dis);
+ }
+
+ /**
+ * Read the TimeRequest in from a given DataInputStream.
+ */
+ public void streamInFrom (DataInputStream dis)
+ throws IOException, EOFException
+ {
+ messageType_ = dis.readInt ();
+ blockForever_ = dis.readInt ();
+ secTimeout_ = dis.readInt ();
+ usecTimeout_ = dis.readInt ();
+ time_ = dis.readInt ();
+ }
+
+ /**
+ * Write this TimeRequest out to a given OutputStream.
+ */
+ public void streamOutTo (OutputStream os)
+ throws IOException
+ {
+ BufferedOutputStream bos = new BufferedOutputStream (os, 25);
+ DataOutputStream dos = new DataOutputStream (bos);
+
+ streamOutTo (dos);
+ }
+
+ /**
+ * Write this TimeRequest out to a given DataOutputStream.
+ */
+ public void streamOutTo (DataOutputStream dos) throws IOException
+ {
+ dos.writeInt (messageType_);
+ dos.writeInt (blockForever_);
+ dos.writeInt (secTimeout_);
+ dos.writeInt (usecTimeout_);
+ dos.writeInt (time_);
+
+ dos.flush ();
+ }
+
+ /**
+ * Return the time value in seconds.
+ */
+ public int time ()
+ {
+ return time_;
+ }
+
+ /**
+ * Set the time value in seconds.
+ */
+ public void time (int value)
+ {
+ time_ = value;
+ }
+
+ private int messageType_;
+ private int blockForever_;
+ private int secTimeout_;
+ private int usecTimeout_;
+ private int time_;
+}
diff --git a/java/JACE/netsvcs/Time/c.bat b/java/JACE/netsvcs/Time/c.bat
new file mode 100644
index 00000000000..5e9e99f5807
--- /dev/null
+++ b/java/JACE/netsvcs/Time/c.bat
@@ -0,0 +1 @@
+javac -d C:\Everett\JACE\classes *.java
diff --git a/java/JACE/netsvcs/Time/package.html b/java/JACE/netsvcs/Time/package.html
new file mode 100644
index 00000000000..96fff45b643
--- /dev/null
+++ b/java/JACE/netsvcs/Time/package.html
@@ -0,0 +1,10 @@
+<!-- $Id$ -->
+<HTML>
+<BODY>
+Time Service for synchronizing clocks of collaborating network computers.
+<P>
+A simple test client is available under the tests directory in netsvcs\Time.
+
+@see <a href="http://www.cs.wustl.edu/~schmidt/ACE-netsvcs.html">ACE Network Services</a>
+</BODY>
+</HTML>
diff --git a/java/JACE/netsvcs/Time/r.bat b/java/JACE/netsvcs/Time/r.bat
new file mode 100644
index 00000000000..7c89fbddd77
--- /dev/null
+++ b/java/JACE/netsvcs/Time/r.bat
@@ -0,0 +1 @@
+java JACE.netsvcs.Time.%1 %2 %3 %4 %5 %6 %7 %8 %9