summaryrefslogtreecommitdiff
path: root/ACE/apps/drwho
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/apps/drwho')
-rw-r--r--ACE/apps/drwho/BS_Client.cpp91
-rw-r--r--ACE/apps/drwho/BS_Client.h46
-rw-r--r--ACE/apps/drwho/BS_Server.cpp120
-rw-r--r--ACE/apps/drwho/BS_Server.h47
-rw-r--r--ACE/apps/drwho/Binary_Search.cpp81
-rw-r--r--ACE/apps/drwho/Binary_Search.h71
-rw-r--r--ACE/apps/drwho/CM_Client.cpp143
-rw-r--r--ACE/apps/drwho/CM_Client.h52
-rw-r--r--ACE/apps/drwho/CM_Server.cpp109
-rw-r--r--ACE/apps/drwho/CM_Server.h39
-rw-r--r--ACE/apps/drwho/ChangeLog399
-rw-r--r--ACE/apps/drwho/Comm_Manager.cpp11
-rw-r--r--ACE/apps/drwho/Comm_Manager.h44
-rw-r--r--ACE/apps/drwho/Drwho_Node.cpp101
-rw-r--r--ACE/apps/drwho/Drwho_Node.h52
-rw-r--r--ACE/apps/drwho/File_Manager.cpp171
-rw-r--r--ACE/apps/drwho/File_Manager.h58
-rw-r--r--ACE/apps/drwho/HT_Client.cpp36
-rw-r--r--ACE/apps/drwho/HT_Client.h31
-rw-r--r--ACE/apps/drwho/HT_Server.cpp39
-rw-r--r--ACE/apps/drwho/HT_Server.h32
-rw-r--r--ACE/apps/drwho/Hash_Table.cpp75
-rw-r--r--ACE/apps/drwho/Hash_Table.h45
-rw-r--r--ACE/apps/drwho/Makefile.am212
-rw-r--r--ACE/apps/drwho/Multicast_Manager.cpp182
-rw-r--r--ACE/apps/drwho/Multicast_Manager.h58
-rw-r--r--ACE/apps/drwho/Options.cpp156
-rw-r--r--ACE/apps/drwho/Options.h66
-rw-r--r--ACE/apps/drwho/PMC_All.cpp101
-rw-r--r--ACE/apps/drwho/PMC_All.h37
-rw-r--r--ACE/apps/drwho/PMC_Flo.cpp125
-rw-r--r--ACE/apps/drwho/PMC_Flo.h37
-rw-r--r--ACE/apps/drwho/PMC_Ruser.cpp179
-rw-r--r--ACE/apps/drwho/PMC_Ruser.h40
-rw-r--r--ACE/apps/drwho/PMC_Usr.cpp117
-rw-r--r--ACE/apps/drwho/PMC_Usr.h38
-rw-r--r--ACE/apps/drwho/PMS_All.cpp101
-rw-r--r--ACE/apps/drwho/PMS_All.h35
-rw-r--r--ACE/apps/drwho/PMS_Flo.cpp76
-rw-r--r--ACE/apps/drwho/PMS_Flo.h35
-rw-r--r--ACE/apps/drwho/PMS_Ruser.cpp134
-rw-r--r--ACE/apps/drwho/PMS_Ruser.h37
-rw-r--r--ACE/apps/drwho/PMS_Usr.cpp83
-rw-r--r--ACE/apps/drwho/PMS_Usr.h35
-rw-r--r--ACE/apps/drwho/PM_Client.cpp140
-rw-r--r--ACE/apps/drwho/PM_Client.h45
-rw-r--r--ACE/apps/drwho/PM_Server.cpp83
-rw-r--r--ACE/apps/drwho/PM_Server.h41
-rw-r--r--ACE/apps/drwho/Protocol_Manager.cpp88
-rw-r--r--ACE/apps/drwho/Protocol_Manager.h58
-rw-r--r--ACE/apps/drwho/Protocol_Record.cpp97
-rw-r--r--ACE/apps/drwho/Protocol_Record.h49
-rw-r--r--ACE/apps/drwho/README308
-rw-r--r--ACE/apps/drwho/Rwho_DB_Manager.cpp126
-rw-r--r--ACE/apps/drwho/Rwho_DB_Manager.h53
-rw-r--r--ACE/apps/drwho/SL_Client.cpp15
-rw-r--r--ACE/apps/drwho/SL_Client.h33
-rw-r--r--ACE/apps/drwho/SL_Server.cpp26
-rw-r--r--ACE/apps/drwho/SL_Server.h34
-rw-r--r--ACE/apps/drwho/SML_Client.cpp36
-rw-r--r--ACE/apps/drwho/SML_Client.h36
-rw-r--r--ACE/apps/drwho/SML_Server.cpp11
-rw-r--r--ACE/apps/drwho/SML_Server.h29
-rw-r--r--ACE/apps/drwho/SMR_Client.cpp22
-rw-r--r--ACE/apps/drwho/SMR_Client.h29
-rw-r--r--ACE/apps/drwho/SMR_Server.cpp18
-rw-r--r--ACE/apps/drwho/SMR_Server.h29
-rw-r--r--ACE/apps/drwho/SM_Client.cpp75
-rw-r--r--ACE/apps/drwho/SM_Client.h38
-rw-r--r--ACE/apps/drwho/SM_Server.cpp69
-rw-r--r--ACE/apps/drwho/SM_Server.h36
-rw-r--r--ACE/apps/drwho/Search_Struct.cpp23
-rw-r--r--ACE/apps/drwho/Search_Struct.h41
-rw-r--r--ACE/apps/drwho/Select_Manager.cpp8
-rw-r--r--ACE/apps/drwho/Select_Manager.h32
-rw-r--r--ACE/apps/drwho/Single_Lookup.cpp32
-rw-r--r--ACE/apps/drwho/Single_Lookup.h39
-rw-r--r--ACE/apps/drwho/client.cpp66
-rw-r--r--ACE/apps/drwho/drwho.mpc94
-rw-r--r--ACE/apps/drwho/global.h52
-rw-r--r--ACE/apps/drwho/server.cpp117
81 files changed, 5905 insertions, 0 deletions
diff --git a/ACE/apps/drwho/BS_Client.cpp b/ACE/apps/drwho/BS_Client.cpp
new file mode 100644
index 00000000000..95f2ea940d7
--- /dev/null
+++ b/ACE/apps/drwho/BS_Client.cpp
@@ -0,0 +1,91 @@
+// $Id$
+
+#include "Options.h"
+#include "File_Manager.h"
+#include "BS_Client.h"
+#include "ace/Log_Msg.h"
+#include "ace/Null_Mutex.h"
+#include "ace/OS_NS_string.h"
+
+BS_Client::BS_Client (void)
+{
+ this->count_ = FILE_MANAGER::instance ()->open_file (Options::friend_file);
+
+ if (this->count_ < 0)
+ ACE_ERROR ((LM_ERROR,
+ "%p\n",
+ Options::program_name));
+ else
+ {
+ ACE_NEW (this->protocol_record_,
+ Protocol_Record[this->count_]);
+ ACE_NEW (this->sorted_record_,
+ Protocol_Record *[this->count_]);
+
+ for (int i = 0; i < this->count_; i++)
+ {
+ Protocol_Record *prp = &this->protocol_record_[i];
+
+ this->sorted_record_[i] = prp;
+
+ FILE_MANAGER::instance ()->get_login_and_real_name
+ (prp->key_name1_, prp->key_name2_);
+ }
+
+ ACE_OS::qsort (this->sorted_record_,
+ this->count_,
+ sizeof *this->sorted_record_,
+ (ACE_COMPARE_FUNC)Binary_Search::name_compare);
+ }
+}
+
+// This function is used to merge the KEY_NAME from server HOST_NAME
+// into the sorted list of userids kept on the client's side. Since
+// we *know* we are going to find the name we use the traditional
+// binary search.
+
+Protocol_Record *
+BS_Client::insert (const char *key_name, int)
+{
+#if 0
+ Protocol_Record *pr = (Protocol_Record *)
+ ACE_OS::bsearch ((const void *) key_name,
+ (const void *) this->sorted_record_,
+ this->count_,
+ sizeof ...,
+ int (*compar)(const void *, const void *) ACE_OS::strcmp);
+ return pr;
+#else
+ int lo = 0;
+ int hi = this->count_ - 1;
+ Protocol_Record **sorted_buffer = this->sorted_record_;
+
+ while (lo <= hi)
+ {
+ int mid = (lo + hi) / 2;
+ Protocol_Record *prp = sorted_buffer[mid];
+ int cmp = ACE_OS::strcmp (key_name,
+ prp->get_login ());
+ if (cmp == 0)
+ return prp;
+ else if (cmp < 0)
+ hi = mid - 1;
+ else
+ lo = mid + 1;
+ }
+
+ return 0;
+#endif /* 0 */
+}
+
+Protocol_Record *
+BS_Client::get_each_entry (void)
+{
+ for (Protocol_Record *prp = Binary_Search::get_each_entry ();
+ prp != 0;
+ prp = Binary_Search::get_each_entry ())
+ if (prp->get_drwho_list () != 0)
+ return prp;
+
+ return 0;
+}
diff --git a/ACE/apps/drwho/BS_Client.h b/ACE/apps/drwho/BS_Client.h
new file mode 100644
index 00000000000..9859768df82
--- /dev/null
+++ b/ACE/apps/drwho/BS_Client.h
@@ -0,0 +1,46 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// BS_Client.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _BS_CLIENT_H
+#define _BS_CLIENT_H
+
+#include "Binary_Search.h"
+
+class BS_Client : public Binary_Search
+{
+ // = TITLE
+ // Provides the client's binary search lookup table abstraction.
+public:
+ // = Initialization.
+ BS_Client (void);
+ // Constructor.
+
+ virtual Protocol_Record *insert (const char *key_name,
+ int max_len = MAXUSERIDNAMELEN);
+ // This function is used to merge the <key_name> from server
+ // <host_name> into the sorted list of userids kept on the client's
+ // side. Since we *know* we are going to find the name we use the
+ // traditional binary search.
+
+ virtual Protocol_Record *get_each_entry (void);
+ // An iterator, similar to Binary_Search::get_next_friend, though in
+ // this case the friend records are returned in the order they
+ // appeared in the friend file, rather than in sorted order. Also,
+ // we skip over entries that don't have any hosts associated with
+ // them.
+};
+
+#endif /* _BS_CLIENT_H */
diff --git a/ACE/apps/drwho/BS_Server.cpp b/ACE/apps/drwho/BS_Server.cpp
new file mode 100644
index 00000000000..057fbc25a04
--- /dev/null
+++ b/ACE/apps/drwho/BS_Server.cpp
@@ -0,0 +1,120 @@
+// $Id$
+
+#include "BS_Server.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_Memory.h"
+#include "ace/os_include/os_netdb.h"
+
+// This constructor takes a message of sorted login names and loads up
+// the symbol table on the server's side. It assumes that the number
+// of friends is stored in the first MAXUSERIDNAMELEN bytes of the
+// packet. Note that we assume that the client sends the login names
+// in sorted order, so we don't bother sorting them!
+
+BS_Server::BS_Server (const char *packet)
+{
+ const char *buf_ptr = packet + MAXUSERIDNAMELEN;
+
+ this->count_ = ACE_OS::atoi (packet);
+ this->buffer_ = buf_ptr;
+
+ ACE_NEW (this->protocol_record_,
+ Protocol_Record[this->count_]);
+ ACE_NEW (this->sorted_record_,
+ Protocol_Record *[this->count_]);
+
+ for (int i = 0; i < this->count_; i++)
+ {
+ Protocol_Record *rec_ptr = &this->protocol_record_[i];
+
+ this->sorted_record_[i] = rec_ptr;
+ rec_ptr->key_name1_ = buf_ptr;
+
+ // Skip forward to the start of the next login name.
+
+ while (*buf_ptr++ != '\0')
+ continue;
+ }
+
+}
+
+// Insert the HOST_NAME into the appropriate DRWHO_LIST slot if the
+// KEY_NAME happens to be one of our friends. Binary search is used
+// because the Protocol_Manager keeps a sorted representation of the
+// friend names.
+//
+// Note that this binary search is tuned for unsuccessful searches,
+// since most of the time we the KEY_NAME is *not* a friend (unless
+// you've got *lots* of friends)!
+//
+// Note finally that we keep a cache of the last KEY_NAME that is
+// looked up, as well as the result of the lookup. This speeds things
+// up because the whod files tend to cluster userids together. */
+
+Protocol_Record *
+BS_Server::insert (const char *key_name, int max_len)
+{
+ static char last_lookup[MAXHOSTNAMELEN];
+ static int mid = 0;
+ static int result = 0;
+ Protocol_Record **buffer = this->sorted_record_;
+
+ // First check the cache...
+ if (ACE_OS::strncmp (last_lookup, key_name, max_len) == 0)
+ {
+ if (result == 0)
+ return 0;
+ }
+ else
+ {
+ // Store this away in the cache for the next iteration.
+ ACE_OS::strncpy (last_lookup, key_name, max_len);
+
+ int hi = this->count_ - 1;
+ int lo = 0;
+ int cmp = 0;
+
+ while (lo < hi)
+ {
+ mid = (hi + lo + 1) / 2;
+
+ cmp = ACE_OS::strncmp (key_name,
+ buffer[mid]->get_login (),
+ max_len);
+ if (cmp < 0)
+ hi = mid - 1;
+ else
+ lo = mid;
+ }
+
+ // This line is very subtle... ;-)
+ if (!(cmp == 0
+ || ACE_OS::strncmp (key_name, buffer[--mid]->get_login (), max_len) == 0))
+ {
+ result = 0;
+ return 0;
+ }
+ }
+
+ // If we get here we've located a friend.
+
+ result = 1;
+ return buffer[mid];
+}
+
+// Returns the next friend in the sequence of sorted friends. Skips
+// over the entries that don't have any hosts associated with them
+// (because these entries weren't on the server machine. */
+
+Protocol_Record *
+BS_Server::get_next_entry (void)
+{
+ for (Protocol_Record *prp = Binary_Search::get_next_entry ();
+ prp != 0;
+ prp = Binary_Search::get_next_entry ())
+ if (prp->get_drwho_list () != 0)
+ return prp;
+
+ return 0;
+}
diff --git a/ACE/apps/drwho/BS_Server.h b/ACE/apps/drwho/BS_Server.h
new file mode 100644
index 00000000000..3c7c1a82afc
--- /dev/null
+++ b/ACE/apps/drwho/BS_Server.h
@@ -0,0 +1,47 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// BS_Server.h
+//
+// = DESCRIPTION
+// Provides the server's binary search lookup table abstraction.
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _BS_SERVER_H
+#define _BS_SERVER_H
+
+#include "Binary_Search.h"
+
+class BS_Server : public Binary_Search
+{
+ // = TITLE
+ // Provides the server's binary search lookup table abstraction.
+public:
+ // = Initialization.
+ BS_Server (const char *packet);
+
+ virtual Protocol_Record *insert (const char *key_name,
+ int max_len = MAXUSERIDNAMELEN);
+ // This function is used to merge the <key_name> from server
+ // <host_name> into the sorted list of userids kept on the client's
+ // side.
+
+ virtual Protocol_Record *get_next_entry (void);
+ // An iterator, similar to Binary_Search::get_next_friend, though in
+ // this case the friend records are returned in the order they
+ // appeared in the friend file, rather than in sorted order. Also,
+ // we skip over entries that don't have any hosts associated with
+ // them.
+};
+
+#endif /* _BS_SERVER_H */
diff --git a/ACE/apps/drwho/Binary_Search.cpp b/ACE/apps/drwho/Binary_Search.cpp
new file mode 100644
index 00000000000..b4c39de27be
--- /dev/null
+++ b/ACE/apps/drwho/Binary_Search.cpp
@@ -0,0 +1,81 @@
+// $Id$
+
+#include "Options.h"
+#include "Binary_Search.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+
+// This function is passed to qsort to perform the comparison between
+// login names for two friends.
+
+int
+Binary_Search::name_compare (const void *s1, const void *s2)
+{
+ return ACE_OS::strcmp ((*(Protocol_Record **) s1)->key_name1_,
+ (*(Protocol_Record **) s2)->key_name1_);
+}
+
+// Returns the next friend in the sequence of sorted friends. Note
+// that this function would be simplified if we expanded the iterator
+// interface to include an "initialize" and "next" function!
+
+Protocol_Record *
+Binary_Search::get_next_entry (void)
+{
+ // Reset the iterator if we are starting from the beginning.
+
+ if (this->current_ptr_ == 0)
+ this->current_ptr_ = this->sorted_record_;
+
+ // Now check to see if we've hit the end, in which case we set
+ // things up for the next round!
+
+ if (this->current_ptr_ < this->sorted_record_ + this->count_)
+ return *this->current_ptr_++;
+ else
+ {
+ this->current_ptr_ = 0;
+ return 0;
+ }
+}
+
+// An iterator, similar to Binary_Search::get_next_friend, though in
+// this case the friend records are returned in the order they
+// appeared in the friend file, rather than in sorted order. Also, we
+// skip over entries that don't have any hosts associated with them.
+
+Protocol_Record *
+Binary_Search::get_each_entry (void)
+{
+ // Reset the iterator if we are starting from the beginning.
+
+ if (this->current_index_ == -1)
+ this->current_index_ = 0;
+
+ // Now check to see if we've hit the end, in which case we set
+ // things up for the next round!
+
+ for (;
+ this->current_index_ < this->count_;
+ this->current_index_++)
+ if (this->protocol_record_[this->current_index_].drwho_list_ != 0)
+ return &this->protocol_record_[this->current_index_++];
+
+ this->current_index_ = -1;
+ return 0;
+}
+
+Binary_Search::~Binary_Search (void)
+{
+ if (Options::get_opt (Options::DEBUG))
+ ACE_DEBUG ((LM_DEBUG,
+ "disposing Binary_Search\n"));
+}
+
+// Used to initialize the values for the iterators...
+
+Binary_Search::Binary_Search (void)
+ : current_ptr_ (0),
+ current_index_ (0)
+{
+}
diff --git a/ACE/apps/drwho/Binary_Search.h b/ACE/apps/drwho/Binary_Search.h
new file mode 100644
index 00000000000..ae8dc93cb29
--- /dev/null
+++ b/ACE/apps/drwho/Binary_Search.h
@@ -0,0 +1,71 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// Binary_Search.h
+//
+// = DESCRIPTION
+// Defines a binary search abstraction for friend records.
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _BINARY_SEARCH_H
+#define _BINARY_SEARCH_H
+
+#include "Search_Struct.h"
+
+class Binary_Search : public Search_Struct
+{
+ // = TITLE
+ // Defines a binary search abstraction for friend records.
+public:
+ // = Initialization and termination method.
+ Binary_Search (void);
+ // Initialize the values for the iterators...
+
+ virtual ~Binary_Search (void);
+ // Destructor.
+
+ virtual Protocol_Record *get_next_entry (void);
+ // Returns the next friend in the sequence of sorted friends. Note
+ // that this function would be simplified if we expanded the
+ // iterator interface to include an "initialize" and "next"
+ // function!
+
+ virtual Protocol_Record *get_each_entry (void);
+ // An iterator, similar to Binary_Search::get_next_friend, though in
+ // this case the friend records are returned in the order they
+ // appeared in the friend file, rather than in sorted order. Also,
+ // we skip over entries that don't have any hosts associated with
+ // them.
+
+ virtual Protocol_Record *insert (const char *key_name,
+ int max_len = MAXUSERIDNAMELEN) = 0;
+ // This function is used to merge the <key_name> from server
+ // <host_name> into the sorted list of userids kept on the client's
+ // side.
+
+ static int name_compare (const void *, const void *);
+ // This function is passed to qsort to perform the comparison
+ // between login names for two friends.
+
+protected:
+ Protocol_Record **current_ptr_;
+ int current_index_;
+
+ Protocol_Record *protocol_record_;
+ Protocol_Record **sorted_record_;
+
+ const char *buffer_;
+ int buffer_size_;
+};
+
+#endif /* _BINARY_SEARCH_H */
diff --git a/ACE/apps/drwho/CM_Client.cpp b/ACE/apps/drwho/CM_Client.cpp
new file mode 100644
index 00000000000..970529a59d3
--- /dev/null
+++ b/ACE/apps/drwho/CM_Client.cpp
@@ -0,0 +1,143 @@
+// $Id$
+
+#include "Options.h"
+#include "Multicast_Manager.h"
+#include "CM_Client.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_sys_socket.h"
+#include "ace/OS_NS_sys_select.h"
+#include "ace/OS_NS_netdb.h"
+#include "ace/OS_NS_arpa_inet.h"
+#include "ace/os_include/os_string.h"
+
+// Creates and binds a UDP socket...
+
+int
+CM_Client::open (short port_number)
+{
+ Comm_Manager::sokfd_ = ACE_OS::socket (PF_INET, SOCK_DGRAM, 0);
+
+ if (Comm_Manager::sokfd_ == ACE_INVALID_HANDLE)
+ return -1;
+
+ ACE_OS::memset ((char *) &this->sin_,
+ 0,
+ sizeof this->sin_);
+ this->sin_.sin_family = AF_INET;
+ this->sin_.sin_port = htons (port_number);
+
+ return 1;
+}
+
+int
+CM_Client::receive (int timeout)
+{
+ FD_ZERO (&this->read_fd_);
+ FD_SET (Comm_Manager::sokfd_, &this->read_fd_);
+
+ if (timeout > 0)
+ {
+ this->time_out_.sec (timeout);
+ this->time_out_.usec (0);
+ this->top_ = &time_out_;
+ }
+
+ while (Multicast_Manager::outstanding_hosts_remain ())
+ {
+ if (ACE_OS::select (Comm_Manager::sokfd_ + 1,
+ &this->read_fd_,
+ 0,
+ 0,
+ this->top_) <= 0)
+ break;
+ else
+ {
+ int sin_len = sizeof this->sin_;
+ int n = ACE_OS::recvfrom ((int)Comm_Manager::sokfd_,
+ this->recv_packet_,
+ UDP_PACKET_SIZE,
+ 0,
+ reinterpret_cast<sockaddr *> (&this->sin_),
+ &sin_len);
+ if (n < 0)
+ return -1;
+ else
+ {
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ hostent *np = ACE_OS::gethostbyaddr ((char *) &this->sin_.sin_addr,
+ sizeof this->sin_.sin_addr,
+ AF_INET);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "receiving from server host %s (%s)\n",
+ np->h_name,
+ ACE_OS::inet_ntoa (this->sin_.sin_addr)));
+ }
+
+ if (this->demux (this->recv_packet_, n) < 0)
+ return -1;
+
+ Multicast_Manager::checkoff_host (this->sin_.sin_addr);
+ }
+ }
+ }
+
+ for (const char *host_name;
+ Multicast_Manager::get_next_non_responding_host (host_name);
+ )
+ ACE_DEBUG ((LM_DEBUG,
+ "%s did not respond\n",
+ host_name));
+ return 1;
+}
+
+int
+CM_Client::send (void)
+{
+ int packet_length = 0;
+
+ if (this->mux (this->send_packet_, packet_length) < 0)
+ return -1;
+
+ // Ship off the info to all the hosts.
+
+ while (Multicast_Manager::get_next_host_addr (this->sin_.sin_addr) != 0)
+ {
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ hostent *np = ACE_OS::gethostbyaddr ((char *) &this->sin_.sin_addr,
+ sizeof this->sin_.sin_addr,
+ AF_INET);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "sending to server host %s (%s)\n",
+ np->h_name,
+ inet_ntoa (this->sin_.sin_addr)));
+ }
+
+ if (sendto (Comm_Manager::sokfd_,
+ this->send_packet_,
+ packet_length,
+ 0,
+ reinterpret_cast<sockaddr *> (&this->sin_),
+ sizeof this->sin_) < 0)
+ return -1;
+ }
+ return 1;
+}
+
+CM_Client::CM_Client (void)
+ : top_ (0)
+{
+}
+
+CM_Client::~CM_Client (void)
+{
+ if (Options::get_opt (Options::DEBUG))
+ ACE_DEBUG ((LM_DEBUG,
+ "disposing CM_Client\n"));
+
+ ACE_OS::closesocket ((int)Comm_Manager::sokfd_);
+}
diff --git a/ACE/apps/drwho/CM_Client.h b/ACE/apps/drwho/CM_Client.h
new file mode 100644
index 00000000000..43d3e9e940e
--- /dev/null
+++ b/ACE/apps/drwho/CM_Client.h
@@ -0,0 +1,52 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// CM_Client.h
+//
+// = DESCRIPTION
+// Provides a virtual communcations layer for the client in the
+// drwho program.
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _CM_CLIENT_H
+#define _CM_CLIENT_H
+
+#include "Comm_Manager.h"
+#include "ace/Time_Value.h"
+
+class CM_Client : public Comm_Manager
+{
+ // = TITLE
+ // Provides a virtual communcations layer for the client in the
+ // drwho program.
+public:
+ // = Initialization and termination.
+ CM_Client (void);
+ // Constructor.
+
+ virtual ~CM_Client (void);
+ // Destructor.
+
+ virtual int mux (char *packet, int &packet_length) = 0;
+ virtual int demux (char *packet, int &packet_length) = 0;
+ virtual int open (short port_number);
+ virtual int receive (int timeout = 0);
+ virtual int send (void);
+
+private:
+ fd_set read_fd_;
+ ACE_Time_Value time_out_;
+ ACE_Time_Value *top_;
+};
+
+#endif /* _CM_CLIENT_H */
diff --git a/ACE/apps/drwho/CM_Server.cpp b/ACE/apps/drwho/CM_Server.cpp
new file mode 100644
index 00000000000..96d5385c790
--- /dev/null
+++ b/ACE/apps/drwho/CM_Server.cpp
@@ -0,0 +1,109 @@
+// $Id$
+
+#include "global.h"
+#include "Options.h"
+#include "CM_Server.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_sys_socket.h"
+#include "ace/OS_NS_arpa_inet.h"
+
+// Creates and binds a UDP socket...
+
+int
+CM_Server::open (short port_number)
+{
+ int max_packet_size = UDP_PACKET_SIZE;
+
+ this->sokfd_ = socket (PF_INET, SOCK_DGRAM, 0);
+
+ if (this->sokfd_ < 0)
+ return -1;
+
+ ACE_OS::memset (&this->sin_, sizeof this->sin_, 0);
+ this->sin_.sin_family = AF_INET;
+ this->sin_.sin_port = htons (port_number);
+ this->sin_.sin_addr.s_addr = INADDR_ANY;
+
+ // This call fails if an rflo daemon is already running.
+ if (ACE_OS::bind (this->sokfd_,
+ reinterpret_cast<sockaddr *> (&this->sin_),
+ sizeof this->sin_) < 0)
+ return -1;
+
+ if (ACE_OS::setsockopt (this->sokfd_,
+ SOL_SOCKET,
+ SO_SNDBUF,
+ (char *) &max_packet_size,
+ sizeof max_packet_size) < 0)
+ return -1;
+
+ return 1;
+}
+
+int
+CM_Server::receive (int)
+{
+ int sin_len = sizeof this->sin_;
+
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG, "waiting for client to send...\n"));
+
+ int n = ACE_OS::recvfrom (this->sokfd_,
+ this->recv_packet_,
+ UDP_PACKET_SIZE,
+ 0,
+ reinterpret_cast<sockaddr *> (&this->sin_),
+ (int *) &sin_len);
+ if (n == -1)
+ return -1;
+
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "receiving from client host %s\n",
+ ACE_OS::inet_ntoa (this->sin_.sin_addr)));
+
+ if (this->demux (this->recv_packet_, n) < 0)
+ return -1;
+
+ return 1;
+}
+
+int
+CM_Server::send (void)
+{
+ int packet_length = 0;
+
+ if (this->mux (this->send_packet_,
+ packet_length) < 0)
+ return -1;
+
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "sending to client host %s\n",
+ ACE_OS::inet_ntoa (this->sin_.sin_addr)));
+
+ if (sendto (this->sokfd_,
+ this->send_packet_,
+ packet_length,
+ 0,
+ reinterpret_cast<sockaddr *> (&this->sin_),
+ sizeof this->sin_) < 0)
+ return -1;
+
+ return 1;
+}
+
+CM_Server::CM_Server (void)
+{
+}
+
+CM_Server::~CM_Server (void)
+{
+ if (Options::get_opt (Options::DEBUG))
+ ACE_DEBUG ((LM_DEBUG,
+ "CM_Server\n"));
+
+ ACE_OS::closesocket (this->sokfd_);
+}
diff --git a/ACE/apps/drwho/CM_Server.h b/ACE/apps/drwho/CM_Server.h
new file mode 100644
index 00000000000..a91402a5e48
--- /dev/null
+++ b/ACE/apps/drwho/CM_Server.h
@@ -0,0 +1,39 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// CM_Server.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _CM_SERVER_H
+#define _CM_SERVER_H
+
+#include "Options.h"
+#include "global.h"
+#include "Comm_Manager.h"
+
+class CM_Server : public Comm_Manager
+{
+ // = TITLE
+ // Provides a virtual communcations layer for the server in drwho.
+public:
+ CM_Server (void);
+ virtual ~CM_Server (void);
+
+ virtual int open (short port_number);
+ virtual int receive (int timeout = 0);
+ virtual int send (void);
+ virtual int mux (char *packet, int &packet_length) = 0;
+ virtual int demux (char *packet, int &packet_length) = 0;
+};
+
+#endif /* _CM_SERVER_H */
diff --git a/ACE/apps/drwho/ChangeLog b/ACE/apps/drwho/ChangeLog
new file mode 100644
index 00000000000..2d2b707b4e0
--- /dev/null
+++ b/ACE/apps/drwho/ChangeLog
@@ -0,0 +1,399 @@
+Thu Jan 5 00:43:30 UTC 2006 J.T. Conklin <jtc@acorntoolworks.com>
+
+ * ChangeLog:
+
+ Untabify.
+ Delete-trailing-whitespace.
+
+Wed Jan 4 22:57:37 UTC 2006 J.T. Conklin <jtc@acorntoolworks.com>
+
+ * ChangeLog:
+
+ Added "Local Variables" section defining "add-log-time-format"
+ to a really ugly lambda expression that formats changelog
+ timestamps in UTC and works with both GNU Emacs and XEmacs.
+
+Mon Nov 28 07:24:01 2005 Ossama Othman <ossama@dre.vanderbilt.edu>
+
+ * drwho.mpc:
+
+ Added missing "avoid += ace_for_tao" for "server" project.
+
+Sat Nov 26 06:58:23 2005 Ossama Othman <ossama@dre.vanderbilt.edu>
+
+ * drwho.mpc:
+
+ Added "avoids += ace_for_tao" since this project requires
+ features of ACE not found in the ace_for_tao subset. Addresses
+ build errors.
+
+Sat Apr 30 08:16:42 2005 Ossama Othman <ossama@dre.vanderbilt.edu>
+
+ * Select_Manager.cpp:
+
+ Fixed syntax error due to missing ACE_RCSID macro definition.
+
+Fri Apr 29 23:54:07 2005 Ossama Othman <ossama@dre.vanderbilt.edu>
+
+ * Comm_Manager.h:
+ * Select_Manager.h:
+
+ Added virtual destructor to silence g++ 4.0 warnings.
+
+ * Comm_Manager.cpp:
+ * Select_Manager.cpp:
+
+ New files containing virtual destructor definition.
+
+ * Makefile.am:
+ * drwho.mpc:
+
+ Added new Comm_Manager.cpp and Select_Manager.cpp files to the
+ source file list.
+
+Sat Feb 17 08:33:06 2001 Douglas C. Schmidt <schmidt@ace.cs.wustl.edu>
+
+ * File_Manager.cpp: Fixed several unreachable statements.
+
+Thu Feb 15 06:00:12 2001 Douglas C. Schmidt <schmidt@ace.cs.wustl.edu>
+
+ * server.cpp: Renamed tstamp to time_stamp to avoid conflicts with
+ the pre-processor on the Forte 5.2 compiler. Thanks to Mike
+ Curtis for reporting this.
+
+ * File_Manager.cpp: Fixed "unreachable code" errors reported by
+ Compaq C++.
+
+Thu Nov 16 17:58:10 2000 Carlos O'Ryan <coryan@uci.edu>
+
+ * Options.h:
+ Fixed small syntax error.
+
+Sat Nov 4 18:18:06 2000 Carlos O'Ryan <coryan@uci.edu>
+
+ * Rwho_DB_Manager.cpp:
+ Add missing #include
+
+Fri Jul 14 14:44:43 2000 Douglas C. Schmidt <schmidt@ace.cs.wustl.edu>
+
+ * CM_Server.cpp (receive): Added a cast to (int *) so that
+ certain C++ compilers are happy. Thanks to John Mills
+ <jmills@tga.com> for reporting this.
+
+Tue May 23 20:52:29 2000 David L. Levine <levine@cs.wustl.edu>
+
+ * CM_Server.cpp (receive): one last time. Use
+ ACE_OS::recvfrom instead of the direct system call,
+ so it hides the native socklen_t or whatever the OS
+ uses.
+
+Tue May 23 07:11:53 2000 David L. Levine <levine@cs.wustl.edu>
+
+ * CM_Server.cpp (receive): changed type of local sin_len
+ to be dependent on ACE_HAS_SOCKLEN_T or ACE_HAS_SIZET_SOCKET_LEN.
+ See Mon May 22 21:10:24 2000 David L. Levine <levine@cs.wustl.edu>
+
+Mon May 22 21:10:24 2000 David L. Levine <levine@cs.wustl.edu>
+
+ * CM_Server.cpp (receive): changed type of local sin_len
+ from int to size_t, to avoid warning from g++ on Linux
+ about "change of signedness". Note that it would be
+ better to use ACE_SOCKET_LEN, but that's defined in
+ ace/OS.i. So, it wouldn't be visible with inlining
+ disabled.
+
+Mon May 22 21:07:57 2000 David L. Levine <levine@cs.wustl.edu>
+
+ * BS_Server.cpp (insert): initialize local cmp to 0, to
+ prevent warning from g++ 2.91.66 (on Linux) about possible
+ use without initialization.
+
+Fri May 5 10:40:46 2000 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * Fixed a coule of errors due to mismatches between int and size_t.
+ Thanks to David Levine and Darrell Brunsch for reporting these.
+
+Thu Apr 20 09:20:28 2000 Carlos O'Ryan <coryan@uci.edu>
+
+ * Drwho_Node.cpp:
+ * File_Manager.cpp:
+ * HT_Client.cpp:
+ * HT_Server.cpp:
+ * Hash_Table.cpp:
+ * Makefile:
+ * PMC_All.cpp:
+ * PMC_Flo.cpp:
+ * PMC_Ruser.cpp:
+ * PMC_Usr.cpp:
+ * PMS_All.cpp:
+ * PMS_Flo.cpp:
+ * PMS_Ruser.cpp:
+ * PMS_Usr.cpp:
+ * PM_Client.cpp:
+ * PM_Server.cpp:
+ * Protocol_Manager.cpp:
+ * Protocol_Record.cpp:
+ * Rwho_DB_Manager.cpp:
+ * Single_Lookup.cpp:
+ * server.cpp:
+ Fixed many warnings wrt order of fields in the initialization
+ section.
+ Add missing template instantiation.
+ Add missing includes.
+ Fixed problems with the scope of variables declared inside a
+ for() loop.
+
+Wed Sep 30 13:00:52 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * Fixed a bunch of warnings related to char * and const char *.
+ Thanks to Sandro Doro <doros@aureus.sublink.org> for reporting
+ this.
+
+Sat Sep 12 21:21:01 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * Made zillions of changes to "ACE"ify all of the code. Drwho is
+ now officially working again!
+
+Sun Sep 6 22:48:52 1998 Douglas C. Schmidt <schmidt@tango.cs.wustl.edu>
+
+ * Replaced all Str::*() methods with the new ACE::*() methods,
+ which are more "standard".
+
+ * Began to work on drwho after a 5 year absence...
+
+Sun Feb 14 16:13:10 1993 Douglas C. Schmidt (schmidt at net1.ics.uci.edu)
+
+ * Yow. Once again back at work... This time I fixed things up so
+ that the release compiles properly with Solaris 2.1 C++, g++
+ 2.3.3, and the Sun C++ compiler on Sun OS 4.1.x. To do this I
+ had to change the user-defined memory allocator somewhat, since
+ the Sun C++ compiler was using the global NEW operator to
+ allocate pools of memory behind my back... Naturally, this
+ reaked havoc with the existing version in the server, which
+ returns all the allocated memory to the free list once a request
+ is satisfied. In addition, g++ had a weird multiple
+ inheritance/pure virtual function bug that I fixed by reordering
+ certain pure virtual functions. Oh what fun... ;-) Anyhow,
+ everything is now back in running order!
+
+Sun Dec 6 16:13:21 1992 Douglas C. Schmidt (schmidt at net1.ics.uci.edu)
+
+ * Yow, well, after about 8 months of total neglect I'm finally
+ back at work on this program! The current changes I did today
+ involved getting drwho to compile with g++ 2.3.2. This required
+ a couple of small work arounds in the source code due to bugs,
+ but hey, I guess it is better than nothing right?!
+
+ Also, I had to fix a couple of places where I didn't correctly
+ initialize static variables (the compiler implementations have
+ changed since last year obviously). Also, I've changed a couple
+ of the default server hosts to reflect the fascist policies of
+ our support group ;-) (I've no longer got access to certain
+ servers...)
+
+ Anyhow, I think drwho is once again running with g++, so now I
+ can hand the release over to Ericka... ;-)
+
+Wed May 6 23:12:02 1992 Douglas C. Schmidt (schmidt at net4.ics.uci.edu)
+
+ * There is something horribly wrong with g++ 2.1. Therefore, I
+ had to make a couple of changes in the pmc-rusers.C and
+ pm-client.C files in order to make the blasted thing compile
+ when I had pointers to member functions... Make sure to change
+ this back when g++ is fixed...
+
+Tue Feb 4 11:23:12 1992 Douglas C. Schmidt (schmidt at net6.ics.uci.edu)
+
+ * The blasted program was crashing when there were consecutive
+ newlines in the input file. I fixed
+ File_Manager::get_login_and_real_name and
+ File_Manager::open_friends_file so that they detect and skip
+ over these consecutive newlines.
+
+Thu Nov 21 21:55:00 1991 Douglas C. Schmidt (schmidt at net6.ics.uci.edu)
+
+ * Make the time that drwho uses to consider a host idle be a
+ command-line parameter.
+
+Wed Nov 13 14:24:40 1991 Douglas C. Schmidt (schmidt at bastille.ics.uci.edu)
+
+ * Something else that ought to be done:
+
+ Add a flag to the -R option that allows the hostname to be
+ printed using the internet address and/or the hostname...
+
+Sat Nov 9 13:45:30 1991 Douglas C. Schmidt (schmidt at bastille.ics.uci.edu)
+
+ * Added zillions more changes yet again. We now have an rusers
+ compatibility mode (-R), to go along with the -a, -w, and
+ default (flo) options.
+
+ * Changed the -w option so that it only returns the name of the
+ host machine where the user is logged in. This way, I can say:
+
+ % talk schmidt@`drwho -w schmidt`
+ % rsh `drwho -w schmidt` w
+
+ etc... ;-)
+
+ * Added support for the -L option (print using login name rather
+ than real name). Also added support for the -l option (print
+ out verbosely, a la ls -l!).
+
+Sun Oct 27 21:32:15 1991 Douglas C. Schmidt (schmidt at bastille.ics.uci.edu)
+
+ * Need to complete the -s and -S options to support sorting the
+ output by login name and real name, respectively... In order to
+ support the '*' indication with this scheme we probably need to
+ lists, one for active and one for inactive users!
+
+Tue Oct 22 00:13:21 1991 Douglas C. Schmidt (schmidt at net6.ics.uci.edu)
+
+ * Make another zillion changes...
+
+Sun Oct 20 21:35:24 1991 Douglas C. Schmidt (schmidt at net6.ics.uci.edu)
+
+ * Added support for the -p option to allow setting the client and
+ server port number from the command-line.
+
+ * Things done so far:
+
+ * Owen also wants an new rflo feature (done)
+
+ I also want a version that given a command like:
+
+ whereis omalley
+
+ would return the login where that login is active if there is
+ one (ie. omalley@zola). Then you could have commands like:
+
+ talk `whereis omalley`
+
+ that would find where I am and try to talk to me there.
+
+ * Another neat addition would be: have an option (e.g., `-a') so
+ that rflo would return *all* the users logged in and then look
+ up their names using the yp passwd stuff! (partially done, but
+ not very elegantly yet...). (done)
+
+ * Make the port number a command-line option... (done)
+
+ * we also need think about how to incorporate inheritance and
+ dynamic binding into this thang (probably it can be used for
+ the local/remote split, and also perhaps for the
+ friends/everyone split (see below)). (done)
+
+ * Fix up the options stuff wrt the -F option etc... (done)
+
+ * Have I fixed the is_active shit? (done)
+
+ * we need a "message abstraction" that abstracts away from the
+ details of packets protocols and remote operations protocols.
+ (done).
+
+ * Note, should make an option so we could read the names of the
+ hosts to query from a file... (done)
+
+Fri Oct 18 16:17:39 1991 Douglas C. Schmidt (schmidt at net6.ics.uci.edu)
+
+ * I've made countless changes...
+
+Wed Oct 16 17:42:40 1991 Douglas C. Schmidt (schmidt at net6.ics.uci.edu)
+
+ * Undid the message manager abstraction and merged it in with the
+ Friend_Manager client and server. This really cleans up the
+ interface!
+
+ * Yow, make zillions of important changes to make the
+ client/server split more explicit... Now the Friend_Manager is
+ split into client and server, the message manager is split, and
+ the communications manager is also split. Each file is much
+ smaller and easier to understand!
+
+Mon Oct 14 18:36:55 1991 Douglas C. Schmidt (schmidt at net1.ics.uci.edu)
+
+ * Added support for the -h and -? options, that print out a long
+ and short usage message, respectively.
+
+Tue Oct 1 09:28:29 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu)
+
+ * The -a option works a great deal better too... I added a check
+ in the File_Manager::open_passwd_file routine to strip off the
+ extra subfields in the pw_gecos field, since this info isn't
+ really very useful and makes the "real name" field too long!
+
+ * Added some extra stuff to the Comm_Manager so that I could
+ change the max size of the UDP datagrams that are passed around.
+ As it turns out, I don't really need to do this, but it is more
+ robust this way...
+
+Thu Sep 26 14:00:45 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu)
+
+ * Make sun3 and sun4 subdirectories to help the build process!
+
+ * Changed the UDP port number from 12346 to 12344 so I wouldn't
+ collide with Owen!
+
+ * There is a weird bus error problem on the sun 4s... Hum...
+
+ * Yow, got everything working again...
+
+ * Still to do:
+
+ * Think about fixing the -f option to work correctly for
+ *relative* filenames...
+
+ * Make UDP_BUFFER_SIZE a command-line option...
+
+ * Modify server.C to be started by inetd.
+
+ * For -a option... if they are a friend, use the name from
+ .friend.dta otherwise use the name from the passwd file.
+
+ * Don't forget about:
+
+ delete Friend_Manager::friend_record;
+ delete Friend_Manager::sorted_record;
+
+ Need to figure out a good way to deal with this!
+
+Mon Sep 23 16:09:46 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu)
+
+ * Added a neat feature that now allows the user to specify which
+ hosts to examine by specifying an option ('-F') on the
+ command-line that reads the contents of that file and inserts it
+ into the list of files.
+
+Wed Sep 18 10:46:41 1991 Douglas C. Schmidt (schmidt at bastille.ics.uci.edu)
+
+ * We need to make all the interfaces throughout rflo much more
+ object-oriented, e.g.:
+
+ * Made a host-manager abstraction to handle all the host
+ machine related operations. This makes the options stuff
+ *much* cleaner!
+
+ * Make rflo compile with g++ 1.37.2! Now it compiles with cfront
+ 2.0, Saber C++ 1.0.1 and g++-1.39.0 and g++-1.37.2.
+
+Tue Sep 17 19:02:47 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu)
+
+ * Started merging in the stuff Owen did. I'm trying to maintain a
+ consistent programming style... The Owen stuff adds support for
+ timeouts and fixes problems with returning a count of the number
+ of friends!
+
+Wed Sep 4 10:14:51 1991 Douglas C. Schmidt (schmidt at net4.ics.uci.edu)
+
+ * Things to do:
+
+ * Add comprehensive daemon support for server.C.
+ * Add timeout stuff in case hosts are down!
+ * Talk to support about making a standard daemon.
+ * Fix the problem with returning the number of friends.
+
+Local Variables:
+mode: change-log
+add-log-time-format: (lambda () (progn (setq tz (getenv "TZ")) (set-time-zone-rule "UTC") (setq time (format-time-string "%a %b %e %H:%M:%S %Z %Y" (current-time))) (set-time-zone-rule tz) time))
+indent-tabs-mode: nil
+End:
diff --git a/ACE/apps/drwho/Comm_Manager.cpp b/ACE/apps/drwho/Comm_Manager.cpp
new file mode 100644
index 00000000000..d4d9234c82d
--- /dev/null
+++ b/ACE/apps/drwho/Comm_Manager.cpp
@@ -0,0 +1,11 @@
+#include "Comm_Manager.h"
+
+
+ACE_RCSID (drwho,
+ Comm_Manager,
+ "$Id$")
+
+
+Comm_Manager::~Comm_Manager (void)
+{
+}
diff --git a/ACE/apps/drwho/Comm_Manager.h b/ACE/apps/drwho/Comm_Manager.h
new file mode 100644
index 00000000000..c7e8348b542
--- /dev/null
+++ b/ACE/apps/drwho/Comm_Manager.h
@@ -0,0 +1,44 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// Comm_Manager.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _COMM_MANAGER_H
+#define _COMM_MANAGER_H
+
+#include "global.h"
+#include "ace/os_include/netinet/os_in.h"
+
+class Comm_Manager
+{
+public:
+
+ virtual ~Comm_Manager (void);
+
+ // = TITLE
+ // Provides a virtual communcations layer for the drwho program.
+protected:
+ char recv_packet_[UDP_PACKET_SIZE];
+ char send_packet_[UDP_PACKET_SIZE];
+ sockaddr_in sin_;
+ int sokfd_;
+
+ virtual int mux (char *packet, int &packet_length) = 0;
+ virtual int demux (char *packet, int &packet_length) = 0;
+ virtual int open (short port_number) = 0;
+ virtual int receive (int timeout = 0) = 0;
+ virtual int send (void) = 0;
+};
+
+#endif /* _COMM_MANAGER_H */
diff --git a/ACE/apps/drwho/Drwho_Node.cpp b/ACE/apps/drwho/Drwho_Node.cpp
new file mode 100644
index 00000000000..ab3b66b93f9
--- /dev/null
+++ b/ACE/apps/drwho/Drwho_Node.cpp
@@ -0,0 +1,101 @@
+// $Id$
+
+#include "Drwho_Node.h"
+
+Drwho_Node::Drwho_Node (const char *h_name, Drwho_Node *n)
+ : key_name1_ (h_name),
+ key_name2_ (0),
+ tty_name_ (0),
+ idle_time_ (0),
+ active_count_ (0),
+ inactive_count_ (0),
+ next_ (n)
+{}
+
+Drwho_Node::Drwho_Node (void)
+ : key_name1_ (0),
+ key_name2_ (0),
+ tty_name_ (0),
+ idle_time_ (0),
+ active_count_ (0),
+ inactive_count_ (0),
+ next_ (0)
+{}
+
+const char *
+Drwho_Node::get_login_name (void)
+{
+ return this->key_name1_;
+}
+
+const char *
+Drwho_Node::set_login_name (const char *str)
+{
+ this->key_name1_ = str;
+ return str;
+}
+
+const char *
+Drwho_Node::get_real_name (void)
+{
+ return this->key_name2_;
+}
+
+const char *
+Drwho_Node::set_real_name (const char *str)
+{
+ this->key_name2_ = str;
+ return str;
+}
+
+const char *
+Drwho_Node::get_host_name (void)
+{
+ return this->key_name1_;
+}
+
+const char *
+Drwho_Node::set_host_name (const char *str)
+{
+ this->key_name1_ = str;
+ return str;
+}
+
+int
+Drwho_Node::get_active_count (void)
+{
+ return this->active_count_;
+}
+
+int
+Drwho_Node::get_inactive_count (void)
+{
+ return this->inactive_count_;
+}
+
+int
+Drwho_Node::set_active_count (int count)
+{
+ this->active_count_ = count;
+ return count;
+}
+
+int
+Drwho_Node::set_inactive_count (int count)
+{
+ this->inactive_count_ = count;
+ return count;
+}
+
+int
+Drwho_Node::set_idle_time (int idle_time)
+{
+ this->idle_time_ = idle_time;
+ return idle_time;
+}
+
+int
+Drwho_Node::get_idle_time (void)
+{
+ return this->idle_time_;
+}
diff --git a/ACE/apps/drwho/Drwho_Node.h b/ACE/apps/drwho/Drwho_Node.h
new file mode 100644
index 00000000000..02251b669df
--- /dev/null
+++ b/ACE/apps/drwho/Drwho_Node.h
@@ -0,0 +1,52 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// Drwho_Node.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _DRWHO_NODE_H
+#define _DRWHO_NODE_H
+
+#include "global.h"
+
+class Drwho_Node
+{
+ // = TITLE
+ // Stores information about a host for a specific friend.
+public:
+ Drwho_Node (const char *host, Drwho_Node *next);
+ Drwho_Node (void);
+
+ int get_active_count (void);
+ int get_inactive_count (void);
+ int set_active_count (int count);
+ int set_inactive_count (int count);
+ int set_idle_time (int idle_time);
+ int get_idle_time (void);
+ const char *get_host_name (void);
+ const char *set_host_name (const char *str);
+ const char *get_login_name (void);
+ const char *set_login_name (const char *);
+ const char *get_real_name (void);
+ const char *set_real_name (const char *);
+
+ const char *key_name1_;
+ const char *key_name2_;
+ const char *tty_name_;
+ int idle_time_;
+ int active_count_;
+ int inactive_count_;
+ Drwho_Node *next_;
+};
+
+#endif /* _DRWHO_NODE_H */
diff --git a/ACE/apps/drwho/File_Manager.cpp b/ACE/apps/drwho/File_Manager.cpp
new file mode 100644
index 00000000000..74aa7fbb7a0
--- /dev/null
+++ b/ACE/apps/drwho/File_Manager.cpp
@@ -0,0 +1,171 @@
+// $Id$
+
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_pwd.h"
+#include "ace/OS_NS_string.h"
+#include "ace/os_include/os_ctype.h"
+#include "File_Manager.h"
+
+File_Manager::File_Manager (void)
+ : number_of_friends (0),
+ max_key_length (0),
+ buffer_ptr (0),
+ current_ptr (0),
+ buffer_size (0)
+{
+}
+
+// Either opens the friends file (if FILENAME is not a NULL pointer)
+// or opens up the password file. In either case, the number of
+// entries in the file are returned, i.e., number of friends...
+
+int
+File_Manager::open_file (const char *filename)
+{
+ return filename == 0
+ ? this->open_passwd_file ()
+ : this->open_friends_file (filename);
+}
+
+// Returns the next LOGIN_NAME and REAL_NAME from the file.
+
+void
+File_Manager::get_login_and_real_name (const char *&login_name, const char *&real_name)
+{
+ char *buf_ptr = this->current_ptr;
+
+ login_name = buf_ptr;
+
+ // Skip to the end of the login name.
+
+ while (isalnum (*buf_ptr))
+ buf_ptr++;
+
+ *buf_ptr++ = '\0';
+
+ // Now skip over white space to *start* of real name!
+
+ while (isspace (*buf_ptr) || *buf_ptr == '\0')
+ buf_ptr++;
+
+ real_name = buf_ptr;
+
+ while (*buf_ptr++ != '\n')
+ continue;
+
+ // Clear the trailing blanks and junk.
+
+ for (char *tmp_ptr = buf_ptr - 1;
+ isspace (*tmp_ptr);
+ tmp_ptr--)
+ *tmp_ptr = '\0';
+
+ // Skip over consecutive blank lines.
+
+ while (*buf_ptr == '\n')
+ buf_ptr++;
+
+ this->current_ptr = buf_ptr;
+}
+
+// Open up the yp passwd file and slurp all the users in!
+
+int
+File_Manager::open_passwd_file (void)
+{
+ const char *filename = ACE_OS::tempnam ();
+ FILE *fp = ACE_OS::fopen (filename, "w");
+
+ if (fp == 0)
+ return -1;
+
+ passwd *pwent;
+
+ for (ACE_OS::setpwent ();
+ (pwent = ACE_OS::getpwent ()) != 0; )
+ if (*pwent->pw_gecos != '\0')
+ {
+ char *cp = ACE_OS::strchr (pwent->pw_gecos, ',');
+
+ if (cp != 0)
+ *cp = '\0';
+
+ ACE_OS::fprintf (fp,
+ "%-8.8s %s\n",
+ pwent->pw_name,
+ pwent->pw_gecos);
+ this->number_of_friends++;
+ }
+
+ ACE_OS::endpwent ();
+
+ ACE_OS::fclose (fp);
+
+ if (this->mmap_.map (filename) == -1)
+ return -1;
+
+ this->buffer_ptr = (char *) this->mmap_.addr ();
+
+ this->buffer_size = this->mmap_.size ();
+ this->current_ptr = this->buffer_ptr;
+ return this->number_of_friends;
+}
+
+// This function opens up FILENAME and memory maps it in our address
+// space.
+
+int
+File_Manager::open_friends_file (const char *filename)
+{
+ char directory[MAXPATHLEN];
+ const char *pathname = directory;
+
+ // See if we've got a filename or a pathname (i.e., directory/filename).
+
+ if (ACE_OS::strrchr (filename, '/') != 0)
+ // We've got a complete pathname.
+ pathname = filename;
+ else
+ {
+ directory[0] = '\0';
+
+ const char *home = ACE_OS::getenv ("HOME");
+ if (home != 0)
+ {
+ ACE_OS::strcat (directory, home);
+ ACE_OS::strcat (directory, "/");
+ }
+ ACE_OS::strcat (directory, filename);
+ }
+
+ // Do the mmap'ing.
+
+ if (this->mmap_.map (pathname) == -1)
+ return -1;
+
+ this->buffer_ptr = (char *) this->mmap_.addr ();
+
+ this->buffer_size = this->mmap_.size ();
+ this->current_ptr = this->buffer_ptr;
+
+ // Determine how many friends there are by counting the newlines.
+
+ for (char *cp = this->buffer_ptr + this->buffer_size;
+ cp > this->buffer_ptr
+ ;)
+ if (*--cp == '\n')
+ {
+ this->number_of_friends++;
+
+ // Skip consecutive newlines.
+ while (cp[-1] == '\n')
+ --cp;
+ }
+
+ return this->number_of_friends;
+}
+
+#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
+template ACE_Singleton<File_Manager, ACE_Null_Mutex> *
+ ACE_Singleton<File_Manager, ACE_Null_Mutex>::singleton_;
+#endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */
diff --git a/ACE/apps/drwho/File_Manager.h b/ACE/apps/drwho/File_Manager.h
new file mode 100644
index 00000000000..1784b8abcfe
--- /dev/null
+++ b/ACE/apps/drwho/File_Manager.h
@@ -0,0 +1,58 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// File_Manager.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _FILE_MANAGER_H
+#define _FILE_MANAGER_H
+
+#include "global.h"
+#include "ace/Singleton.h"
+#include "ace/Null_Mutex.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Mem_Map.h"
+
+class File_Manager
+{
+ // = TITLE
+ // This class provides a file ADT for our friends info.
+public:
+ File_Manager (void);
+ // Constructor.
+
+ int open_file (const char *filename);
+ void get_login_and_real_name (const char *&login_name,
+ const char *&real_name);
+private:
+ int number_of_friends;
+ int max_key_length;
+
+ char *buffer_ptr;
+ char *current_ptr;
+ int buffer_size;
+
+ int open_friends_file (const char *filename);
+ int open_passwd_file (void);
+
+ ACE_Mem_Map mmap_;
+};
+
+// Make a Singleton.
+typedef ACE_Singleton <File_Manager, ACE_Null_Mutex> FILE_MANAGER;
+
+#endif /* _FILE_MANAGER_H */
diff --git a/ACE/apps/drwho/HT_Client.cpp b/ACE/apps/drwho/HT_Client.cpp
new file mode 100644
index 00000000000..0d3641382cd
--- /dev/null
+++ b/ACE/apps/drwho/HT_Client.cpp
@@ -0,0 +1,36 @@
+// $Id$
+
+#include "HT_Client.h"
+#include "ace/ACE.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_Memory.h"
+
+// Insert a KEY_NAME into the hash table, if it doesn't already exist
+// there. What gets returned is a pointer to the node inserted. Note
+// that we do our own memory allocation here...
+
+Protocol_Record *
+HT_Client::insert (const char *key_name, int max_len)
+{
+ Protocol_Record **prpp = 0;
+
+ // This is tricky...
+
+ for (prpp = &this->hash_table[ACE::hash_pjw (key_name) % this->hash_table_size];
+ *prpp != 0
+ && ACE_OS::strncmp ((*prpp)->get_login (),
+ key_name, max_len) != 0;
+ prpp = &(*prpp)->next_)
+ continue;
+
+ if (*prpp == 0)
+ {
+ ACE_NEW_RETURN (*prpp,
+ Protocol_Record (ACE::strnew (key_name),
+ *prpp),
+ 0);
+ this->count_++;
+ }
+
+ return *prpp;
+}
diff --git a/ACE/apps/drwho/HT_Client.h b/ACE/apps/drwho/HT_Client.h
new file mode 100644
index 00000000000..274cc6e72e6
--- /dev/null
+++ b/ACE/apps/drwho/HT_Client.h
@@ -0,0 +1,31 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// HT_Client.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _HT_CLIENT_H
+#define _HT_CLIENT_H
+
+#include "Hash_Table.h"
+
+class HT_Client : public Hash_Table
+{
+ // = TITLE
+ // Provides the client's hash table abstraction.
+public:
+ virtual Protocol_Record *insert (const char *key_name,
+ int max_len = MAXUSERIDNAMELEN);
+};
+
+#endif /* _HT_CLIENT_H */
diff --git a/ACE/apps/drwho/HT_Server.cpp b/ACE/apps/drwho/HT_Server.cpp
new file mode 100644
index 00000000000..cf52d0804ca
--- /dev/null
+++ b/ACE/apps/drwho/HT_Server.cpp
@@ -0,0 +1,39 @@
+// $Id$
+
+#include "HT_Server.h"
+#include "ace/ACE.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_Memory.h"
+
+// Insert a KEY_NAME into the hash table, if it doesn't already exist
+// there. What gets returned is a pointer to the node inserted. Note
+// that we do our own memory allocation here...
+
+Protocol_Record *
+HT_Server::insert (const char *key_name, int max_len)
+{
+ Protocol_Record **prpp = 0;
+
+ // This is tricky...
+
+ for (prpp = &this->hash_table[ACE::hash_pjw (key_name) % this->hash_table_size];
+ *prpp != 0 && ACE_OS::strncmp ((*prpp)->get_login (), key_name, max_len) != 0;
+ prpp = &(*prpp)->next_)
+ continue;
+
+ if (*prpp == 0)
+ {
+ // Remember, the server must be very careful about stuff it
+ // receives from the rwho manager, since it may not be
+ // NUL-terminated. That's why we use ACE::strnnew ()...
+
+ ACE_NEW_RETURN (*prpp,
+ Protocol_Record (ACE::strnnew (key_name,
+ max_len),
+ *prpp),
+ 0);
+ this->count_++;
+ }
+
+ return *prpp;
+}
diff --git a/ACE/apps/drwho/HT_Server.h b/ACE/apps/drwho/HT_Server.h
new file mode 100644
index 00000000000..3dbff633cfb
--- /dev/null
+++ b/ACE/apps/drwho/HT_Server.h
@@ -0,0 +1,32 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// HT_Server.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _HT_SERVER_H
+#define _HT_SERVER_H
+
+#include "Hash_Table.h"
+
+class HT_Server : public Hash_Table
+{
+ // = TITLE
+ // Provides the server's hash table abstraction.
+
+public:
+ virtual Protocol_Record *insert (const char *key_name,
+ int max_len = MAXUSERIDNAMELEN);
+};
+
+#endif /* _HT_SERVER_H */
diff --git a/ACE/apps/drwho/Hash_Table.cpp b/ACE/apps/drwho/Hash_Table.cpp
new file mode 100644
index 00000000000..574cb71718b
--- /dev/null
+++ b/ACE/apps/drwho/Hash_Table.cpp
@@ -0,0 +1,75 @@
+// $Id$
+
+#include "Options.h"
+#include "Hash_Table.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_Memory.h"
+#include "ace/OS_NS_string.h"
+
+Hash_Table::Hash_Table (void)
+ : current_ptr (0),
+ current_index (0),
+ hash_table_size (HASH_TABLE_SIZE)
+{
+ ACE_NEW (this->hash_table,
+ Protocol_Record *[this->hash_table_size]);
+ ACE_OS::memset (this->hash_table,
+ 0,
+ this->hash_table_size * sizeof *this->hash_table);
+}
+
+// Iterate through the hash table returning one node at a time...
+
+Protocol_Record *
+Hash_Table::get_next_entry (void)
+{
+ // Reset the iterator if we are starting from the beginning.
+
+ if (this->current_index == -1)
+ this->current_index = 0;
+
+ if (this->current_ptr == 0)
+ {
+
+ for (;
+ this->current_index < this->hash_table_size;
+ this->current_index++)
+ if (this->hash_table[this->current_index] != 0)
+ {
+ Protocol_Record *prp = this->hash_table[this->current_index++];
+ this->current_ptr = prp->next_;
+ return prp;
+ }
+
+ this->current_index = -1;
+ return 0;
+ }
+ else
+ {
+ Protocol_Record *prp = this->current_ptr;
+ this->current_ptr = this->current_ptr->next_;
+ return prp;
+ }
+}
+
+Protocol_Record *
+Hash_Table::get_each_entry (void)
+{
+ return this->get_next_entry ();
+}
+
+// Frees up all the dynamic memory in the hash table.
+
+Hash_Table::~Hash_Table (void)
+{
+ if (Options::get_opt (Options::DEBUG))
+ ACE_DEBUG ((LM_DEBUG,
+ "disposing Hash_Table\n"));
+
+ for (int i = 0; i < this->hash_table_size; i++)
+ for (Protocol_Record *prp = this->hash_table[i];
+ prp != 0; )
+ {
+ prp = prp->next_;
+ }
+}
diff --git a/ACE/apps/drwho/Hash_Table.h b/ACE/apps/drwho/Hash_Table.h
new file mode 100644
index 00000000000..44f5ea769fc
--- /dev/null
+++ b/ACE/apps/drwho/Hash_Table.h
@@ -0,0 +1,45 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// HT_Server.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _HASH_TABLE_H
+#define _HASH_TABLE_H
+
+#include "Search_Struct.h"
+
+class Hash_Table : public Search_Struct
+{
+ // = TITLE
+ // Provides a hash function lookup abstraction for friend records.
+public:
+ Hash_Table (void);
+ virtual ~Hash_Table (void);
+ virtual Protocol_Record *insert (const char *key_name,
+ int max_len = MAXUSERIDNAMELEN) = 0;
+ virtual Protocol_Record *get_next_entry (void);
+ virtual Protocol_Record *get_each_entry (void);
+
+protected:
+ enum
+ {
+ HASH_TABLE_SIZE = 500
+ };
+
+ Protocol_Record **hash_table;
+ Protocol_Record *current_ptr;
+ int current_index;
+ int hash_table_size;
+};
+#endif /* _HASH_TABLE_H */
diff --git a/ACE/apps/drwho/Makefile.am b/ACE/apps/drwho/Makefile.am
new file mode 100644
index 00000000000..8a6e815e167
--- /dev/null
+++ b/ACE/apps/drwho/Makefile.am
@@ -0,0 +1,212 @@
+## Process this file with automake to create Makefile.in
+##
+## $Id$
+##
+## This file was generated by MPC. Any changes made directly to
+## this file will be lost the next time it is generated.
+##
+## MPC Command:
+## /acebuilds/ACE_wrappers-repository/bin/mwc.pl -include /acebuilds/MPC/config -include /acebuilds/MPC/templates -feature_file /acebuilds/ACE_wrappers-repository/local.features -noreldefs -type automake -exclude build,Kokyu
+
+ACE_BUILDDIR = $(top_builddir)
+ACE_ROOT = $(top_srcdir)
+
+noinst_PROGRAMS =
+
+## Makefile.drwho__client.am
+
+if BUILD_RWHO
+if !BUILD_ACE_FOR_TAO
+if !BUILD_USES_WCHAR
+noinst_PROGRAMS += client
+
+client_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR)
+
+client_SOURCES = \
+ BS_Client.cpp \
+ BS_Server.cpp \
+ Binary_Search.cpp \
+ CM_Client.cpp \
+ CM_Server.cpp \
+ Comm_Manager.cpp \
+ Drwho_Node.cpp \
+ File_Manager.cpp \
+ HT_Client.cpp \
+ HT_Server.cpp \
+ Hash_Table.cpp \
+ Multicast_Manager.cpp \
+ Options.cpp \
+ PMC_All.cpp \
+ PMC_Flo.cpp \
+ PMC_Ruser.cpp \
+ PMC_Usr.cpp \
+ PMS_All.cpp \
+ PMS_Flo.cpp \
+ PMS_Ruser.cpp \
+ PMS_Usr.cpp \
+ PM_Client.cpp \
+ PM_Server.cpp \
+ Protocol_Manager.cpp \
+ Protocol_Record.cpp \
+ Rwho_DB_Manager.cpp \
+ SL_Client.cpp \
+ SL_Server.cpp \
+ SML_Client.cpp \
+ SML_Server.cpp \
+ SMR_Client.cpp \
+ SMR_Server.cpp \
+ SM_Client.cpp \
+ SM_Server.cpp \
+ Search_Struct.cpp \
+ Select_Manager.cpp \
+ Single_Lookup.cpp \
+ client.cpp \
+ BS_Client.h \
+ BS_Server.h \
+ Binary_Search.h \
+ CM_Client.h \
+ CM_Server.h \
+ Comm_Manager.h \
+ Drwho_Node.h \
+ File_Manager.h \
+ HT_Client.h \
+ HT_Server.h \
+ Hash_Table.h \
+ Multicast_Manager.h \
+ Options.h \
+ PMC_All.h \
+ PMC_Flo.h \
+ PMC_Ruser.h \
+ PMC_Usr.h \
+ PMS_All.h \
+ PMS_Flo.h \
+ PMS_Ruser.h \
+ PMS_Usr.h \
+ PM_Client.h \
+ PM_Server.h \
+ Protocol_Manager.h \
+ Protocol_Record.h \
+ Rwho_DB_Manager.h \
+ SL_Client.h \
+ SL_Server.h \
+ SML_Client.h \
+ SML_Server.h \
+ SMR_Client.h \
+ SMR_Server.h \
+ SM_Client.h \
+ SM_Server.h \
+ Search_Struct.h \
+ Select_Manager.h \
+ Single_Lookup.h
+
+client_LDADD = \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_USES_WCHAR
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_RWHO
+
+## Makefile.drwho__server.am
+
+if BUILD_RWHO
+if !BUILD_ACE_FOR_TAO
+if !BUILD_USES_WCHAR
+noinst_PROGRAMS += server
+
+server_CPPFLAGS = \
+ -I$(ACE_ROOT) \
+ -I$(ACE_BUILDDIR)
+
+server_SOURCES = \
+ BS_Client.cpp \
+ BS_Server.cpp \
+ Binary_Search.cpp \
+ CM_Client.cpp \
+ CM_Server.cpp \
+ Comm_Manager.cpp \
+ Drwho_Node.cpp \
+ File_Manager.cpp \
+ HT_Client.cpp \
+ HT_Server.cpp \
+ Hash_Table.cpp \
+ Multicast_Manager.cpp \
+ Options.cpp \
+ PMC_All.cpp \
+ PMC_Flo.cpp \
+ PMC_Ruser.cpp \
+ PMC_Usr.cpp \
+ PMS_All.cpp \
+ PMS_Flo.cpp \
+ PMS_Ruser.cpp \
+ PMS_Usr.cpp \
+ PM_Client.cpp \
+ PM_Server.cpp \
+ Protocol_Manager.cpp \
+ Protocol_Record.cpp \
+ Rwho_DB_Manager.cpp \
+ SL_Client.cpp \
+ SL_Server.cpp \
+ SML_Client.cpp \
+ SML_Server.cpp \
+ SMR_Client.cpp \
+ SMR_Server.cpp \
+ SM_Client.cpp \
+ SM_Server.cpp \
+ Search_Struct.cpp \
+ Select_Manager.cpp \
+ Single_Lookup.cpp \
+ server.cpp \
+ BS_Client.h \
+ BS_Server.h \
+ Binary_Search.h \
+ CM_Client.h \
+ CM_Server.h \
+ Comm_Manager.h \
+ Drwho_Node.h \
+ File_Manager.h \
+ HT_Client.h \
+ HT_Server.h \
+ Hash_Table.h \
+ Multicast_Manager.h \
+ Options.h \
+ PMC_All.h \
+ PMC_Flo.h \
+ PMC_Ruser.h \
+ PMC_Usr.h \
+ PMS_All.h \
+ PMS_Flo.h \
+ PMS_Ruser.h \
+ PMS_Usr.h \
+ PM_Client.h \
+ PM_Server.h \
+ Protocol_Manager.h \
+ Protocol_Record.h \
+ Rwho_DB_Manager.h \
+ SL_Client.h \
+ SL_Server.h \
+ SML_Client.h \
+ SML_Server.h \
+ SMR_Client.h \
+ SMR_Server.h \
+ SM_Client.h \
+ SM_Server.h \
+ Search_Struct.h \
+ Select_Manager.h \
+ Single_Lookup.h
+
+server_LDADD = \
+ $(ACE_BUILDDIR)/ace/libACE.la
+
+endif !BUILD_USES_WCHAR
+endif !BUILD_ACE_FOR_TAO
+endif BUILD_RWHO
+
+## Clean up template repositories, etc.
+clean-local:
+ -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.*
+ -rm -f gcctemp.c gcctemp so_locations *.ics
+ -rm -rf cxx_repository ptrepository ti_files
+ -rm -rf templateregistry ir.out
+ -rm -rf ptrepository SunWS_cache Templates.DB
diff --git a/ACE/apps/drwho/Multicast_Manager.cpp b/ACE/apps/drwho/Multicast_Manager.cpp
new file mode 100644
index 00000000000..71bb56ee894
--- /dev/null
+++ b/ACE/apps/drwho/Multicast_Manager.cpp
@@ -0,0 +1,182 @@
+// $Id$
+
+#include "Multicast_Manager.h"
+#include "ace/Mem_Map.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_arpa_inet.h"
+#include "ace/OS_NS_netdb.h"
+#include "ace/OS_Memory.h"
+#include "ace/os_include/os_ctype.h"
+
+// Initialize all the static member vars.
+int Multicast_Manager::received_host_count = 0;
+Host_Elem *Multicast_Manager::drwho_list = 0;
+Host_Elem *Multicast_Manager::current_ptr = 0;
+
+// Names of hosts to query for friend info.
+const char *Multicast_Manager::host_names[] =
+{
+ "tango.cs.wustl.edu",
+ 0 // The NULL entry...
+};
+
+void
+Multicast_Manager::insert_default_hosts (void)
+{
+ // Enter the static list of hosts into the dynamic table!
+
+ for (const char **np = host_names;
+ *np != 0;
+ np++)
+ Multicast_Manager::add_host (*np);
+}
+
+// Inserts all the names in FILENAME into the list of hosts to
+// contact.
+
+int
+Multicast_Manager::insert_hosts_from_file (const char *filename)
+{
+ ACE_Mem_Map mmap (filename);
+ char *host_ptr = (char *) mmap.addr ();
+
+ if (host_ptr == 0)
+ return -1;
+ else
+ {
+ for (char *end_ptr = host_ptr + mmap.size ();
+ host_ptr < end_ptr;
+ )
+ {
+ Multicast_Manager::add_host (host_ptr);
+
+ while (*host_ptr != '\n')
+ host_ptr++;
+
+ *host_ptr++ = '\0';
+ }
+
+ return 0;
+ }
+}
+
+// Returns the IP host address for the next unexamined host in the
+// list. If no more unexamined hosts remain a 0 is returned, else a
+// 1.
+
+int
+Multicast_Manager::get_next_host_addr (in_addr &host_addr)
+{
+ for (Multicast_Manager::current_ptr = Multicast_Manager::current_ptr == 0 ? Multicast_Manager::drwho_list : Multicast_Manager::current_ptr->next;
+
+ Multicast_Manager::current_ptr != 0;
+ Multicast_Manager::current_ptr = Multicast_Manager::current_ptr->next)
+ {
+ const char *host_name = Multicast_Manager::current_ptr->host_name;
+ hostent *hp = Multicast_Manager::get_host_entry (host_name);
+
+ if (hp == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "%s: host unknown.\n",
+ host_name));
+ continue;
+ }
+
+ Multicast_Manager::received_host_count++;
+ ACE_OS::memcpy (&host_addr,
+ hp->h_addr,
+ sizeof host_addr);
+ ACE_OS::memcpy (&Multicast_Manager::current_ptr->host_addr,
+ hp->h_addr,
+ sizeof host_addr);
+ return 1;
+ }
+
+ return 0;
+}
+
+// This function attempts to get the internet address for either a
+// hostname or hostnumber. The function makes the simplifying
+// assumption that hostnames begin with an alphabetic character!
+
+hostent *
+Multicast_Manager::get_host_entry (const char *host)
+{
+ static hostent host_entry;
+ hostent *hp;
+
+ if (isdigit (*host)) // IP address.
+ {
+ u_long ia = ACE_OS::inet_addr (host);
+
+ if (ia == (u_long) -1)
+ hp = 0;
+ else
+ hp = ACE_OS::gethostbyaddr ((char *) &ia,
+ sizeof ia,
+ AF_INET);
+ }
+ else
+ // Host name.
+ hp = ACE_OS::gethostbyname (host);
+
+
+ return hp == 0 ? 0 : (hostent *) ACE_OS::memcpy (&host_entry, hp, sizeof *hp);
+}
+
+// Adds an additional new host to the list of host machines.
+
+void
+Multicast_Manager::add_host (const char *host_name)
+{
+ ACE_NEW (Multicast_Manager::drwho_list,
+ Host_Elem (host_name,
+ Multicast_Manager::drwho_list));
+}
+
+void
+Multicast_Manager::checkoff_host (in_addr host_addr)
+{
+ for (Host_Elem *tmp = Multicast_Manager::drwho_list;
+ tmp != 0;
+ tmp = tmp->next)
+ if (ACE_OS::memcmp (&tmp->host_addr.s_addr,
+ &host_addr.s_addr,
+ sizeof host_addr.s_addr) == 0)
+ {
+ tmp->checked_off = 1;
+ Multicast_Manager::received_host_count--;
+ return;
+ }
+}
+
+int
+Multicast_Manager::get_next_non_responding_host (const char *&host_name)
+{
+ for (Multicast_Manager::current_ptr = Multicast_Manager::current_ptr == 0 ? Multicast_Manager::drwho_list : Multicast_Manager::current_ptr->next;
+ Multicast_Manager::current_ptr != 0;
+ Multicast_Manager::current_ptr = Multicast_Manager::current_ptr->next)
+ if (Multicast_Manager::current_ptr->checked_off == 0)
+ {
+ host_name = Multicast_Manager::current_ptr->host_name;
+ return 1;
+ }
+
+ return 0;
+}
+
+Host_Elem::Host_Elem (const char *h_name,
+ Host_Elem *n)
+ : host_name (h_name),
+ checked_off (0),
+ next (n)
+{
+}
+
+int
+Multicast_Manager::outstanding_hosts_remain (void)
+{
+ return Multicast_Manager::received_host_count > 0;
+}
diff --git a/ACE/apps/drwho/Multicast_Manager.h b/ACE/apps/drwho/Multicast_Manager.h
new file mode 100644
index 00000000000..ee21ac6ac08
--- /dev/null
+++ b/ACE/apps/drwho/Multicast_Manager.h
@@ -0,0 +1,58 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// Multicast_Manager.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _MULTICAST_MANAGER_H
+#define _MULTICAST_MANAGER_H
+
+#include "global.h"
+#include "ace/os_include/netinet/os_in.h"
+#include "ace/os_include/os_netdb.h"
+
+class Host_Elem
+{
+public:
+ const char *host_name;
+ in_addr host_addr;
+ int checked_off;
+ Host_Elem *next;
+
+ Host_Elem (const char *h_name, Host_Elem *n);
+};
+
+class Multicast_Manager
+{
+ // = TITLE
+ // This file handles all the operations upon host machines names
+ // and addresses.
+public:
+ static void add_host (const char *host_name);
+ static void checkoff_host (in_addr host_addr);
+ static int get_next_host_addr (in_addr &host_addr);
+ static int outstanding_hosts_remain (void);
+ static int get_next_non_responding_host (const char *&host_name);
+ static int insert_hosts_from_file (const char *filename);
+ static void insert_default_hosts (void);
+
+private:
+ static hostent *get_host_entry (const char *host);
+
+ static int received_host_count;
+ static const char *host_names[];
+ static Host_Elem *drwho_list;
+ static Host_Elem *current_ptr;
+};
+
+#endif /* _MULTICAST_MANAGER_H */
diff --git a/ACE/apps/drwho/Options.cpp b/ACE/apps/drwho/Options.cpp
new file mode 100644
index 00000000000..076623c0e03
--- /dev/null
+++ b/ACE/apps/drwho/Options.cpp
@@ -0,0 +1,156 @@
+// $Id$
+
+#include "ace/OS_NS_stdlib.h"
+#include "ace/Get_Opt.h"
+#include "ace/Log_Msg.h"
+#include "Options.h"
+#include "Multicast_Manager.h"
+
+// Initialize all the static variables.
+
+// Contains bit-mask for options.
+u_int Options::option_word = 0;
+
+// Which protocol are we using?
+Options::Protocol_Types Options::protocol_type = Options::PROTO_FLO;
+
+// User name for quick lookups.
+char *Options::user_name = 0;
+
+// Port number for client/server.
+short Options::port_number = PORT_NUMBER;
+
+// Maximum time the client waits for servers to timeout.
+int Options::max_server_timeout = 5;
+
+// Name of the program.
+char *Options::program_name;
+
+// Default name of file that stores friend info.
+const char *Options::friend_file = FRIEND_FILE;
+
+void
+Options::print_usage_and_die (int long_msg)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "usage: %s %s",
+ program_name,
+ long_msg
+ ? "\n"
+ "-?\tprints a short usage message\n"
+ "-A\tappend the following hostname to the list of predefined hostnames.\n"
+ "-a\treturn information on *all* users remotely logged in (uses yp passwd).\n"
+ "-b\trun the server in the background (i.e., as a daemon).\n"
+ "-d\tturn on debugging.\n"
+ "-F\tuse the following file contents to initialize the host list.\n"
+ "-f\tuse the following file contents to initialize the friends database.\n"
+ "-H\tuse the following hostname as part of the new list of hostnames.\n"
+ "\t(this option overwrites the existing default names).\n"
+ "-h\tprint a long usage message.\n"
+ "-L\tprint the login name rather than the real name (which is the default).\n"
+ "-l\tprint information in long format (works for all protocols).\n"
+ "-p\tset the port number (server must correspond).\n"
+ "-r\tdo the remote lookups (i.e., local operations are the default).\n"
+ "-R\tprint info using the rusers format.\n"
+ "-s\tsort the output by login name.\n"
+ "-S\tsort the output by real name.\n"
+ "-t\tset the amount of time we wait for servers to timeout.\n"
+ "-w\treturn information on just one user.\n"
+ : "[-?haAbdfFHhLlpRrtw]\n"));
+ ACE_OS::exit (1);
+}
+
+void
+Options::set_opt (Option_Types opt)
+{
+ Options::option_word |= opt;
+}
+
+int
+Options::get_opt (Option_Types opt)
+{
+ return (Options::option_word & opt) != 0;
+}
+
+void
+Options::set_options (int argc, char *argv[])
+{
+ int c;
+ int add_default_hosts = 1;
+
+ Options::program_name = argv[0];
+ ACE_Get_Opt getopt (argc, argv, "?aA:bdF:f:hH:Llp:rRsSt:w:");
+
+ while ((c = getopt ()) != -1)
+ {
+ switch (c)
+ {
+ case '?':
+ Options::print_usage_and_die (0);
+ /* NOTREACHED */
+ case 'A':
+ Multicast_Manager::add_host (getopt.opt_arg ());
+ break;
+ case 'a':
+ Options::protocol_type = PROTO_ALL;
+ break;
+ case 'b':
+ Options::set_opt (Options::BE_A_DAEMON);
+ break;
+ case 'd':
+ Options::set_opt (Options::DEBUG);
+ break;
+ case 'f':
+ Options::friend_file = getopt.opt_arg ();
+ break;
+ case 'F':
+ if (Multicast_Manager::insert_hosts_from_file (getopt.opt_arg ()) < 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "%p%a\n",
+ Options::program_name,
+ 1));
+ add_default_hosts = 0;
+ break;
+ case 'H':
+ Multicast_Manager::add_host (getopt.opt_arg ());
+ add_default_hosts = 0;
+ break;
+ case 'h':
+ Options::print_usage_and_die (1);
+ /* NOTREACHED */
+ case 'L':
+ Options::set_opt (Options::PRINT_LOGIN_NAME);
+ break;
+ case 'l':
+ Options::set_opt (Options::USE_VERBOSE_FORMAT);
+ break;
+ case 'p':
+ Options::port_number = ACE_OS::atoi (getopt.opt_arg ());
+ break;
+ case 'R':
+ Options::protocol_type = PROTO_RUSER;
+ break;
+ case 'r':
+ Options::set_opt (Options::REMOTE_USAGE);
+ break;
+ case 's':
+ Options::set_opt (Options::SORT_BY_LOGIN_NAME);
+ break;
+ case 'S':
+ Options::set_opt (Options::SORT_BY_REAL_NAME);
+ break;
+ case 't':
+ Options::max_server_timeout = ACE_OS::atoi (getopt.opt_arg ());
+ break;
+ case 'w':
+ Options::user_name = getopt.opt_arg ();
+ Options::protocol_type = PROTO_USR;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (Options::get_opt (Options::REMOTE_USAGE) && add_default_hosts)
+ Multicast_Manager::insert_default_hosts ();
+}
diff --git a/ACE/apps/drwho/Options.h b/ACE/apps/drwho/Options.h
new file mode 100644
index 00000000000..bfc9d054c43
--- /dev/null
+++ b/ACE/apps/drwho/Options.h
@@ -0,0 +1,66 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// Options.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _OPTIONS_H
+#define _OPTIONS_H
+
+#include "global.h"
+
+class Options
+{
+ // = TITLE
+ // This file is used to provide a consolidated Options handling facility.
+public:
+ enum Option_Types
+ {
+ REMOTE_USAGE = 01,
+ PRINT_LOGIN_NAME = 02,
+ DEBUG = 04,
+ STAND_ALONE_SERVER = 010,
+ SORT_BY_LOGIN_NAME = 020,
+ SORT_BY_REAL_NAME = 040,
+ USE_VERBOSE_FORMAT = 0100,
+ BE_A_DAEMON = 0200
+ };
+
+ // Different types of messages.
+ enum Protocol_Types
+ {
+ PROTO_USR = 1, // Only return info on one user.
+ PROTO_ALL = 2, // Return info on all users logged in around the system.
+ PROTO_FLO = 3, // Return info on friends logged in.
+ PROTO_RUSER = 4, // Return info in ruser format!
+ PROTO_RWHO = 5, // Return info in rwho format.
+ PROTO_WHO = 6, // Return info in who format.
+ PROTO_RUPTIME = 7 // Return info in ruptime format.
+ };
+
+ static void set_options (int argc, char *argv[]);
+ static void set_opt (Option_Types opt);
+ static int get_opt (Option_Types opt);
+
+ static short port_number;
+ static Protocol_Types protocol_type;
+ static int max_server_timeout;
+ static char *program_name;
+ static const char *friend_file;
+ static char *user_name;
+
+ static void print_usage_and_die (int long_msg);
+ static unsigned int option_word;
+};
+
+#endif /* _OPTIONS_H */
diff --git a/ACE/apps/drwho/PMC_All.cpp b/ACE/apps/drwho/PMC_All.cpp
new file mode 100644
index 00000000000..2ab885e1628
--- /dev/null
+++ b/ACE/apps/drwho/PMC_All.cpp
@@ -0,0 +1,101 @@
+// $Id$
+
+#include "global.h"
+#include "Options.h"
+#include "HT_Client.h"
+#include "PMC_All.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_Memory.h"
+
+// This function is pretty much a no-op that just sets up the
+// appropriate lookup function to use.
+
+int
+PMC_All::encode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMC_All::encode\n"));
+
+ ACE_NEW_RETURN (this->ss,
+ HT_Client,
+ -1);
+
+ SET_PACKET_TYPE (packet, Options::PROTO_ALL);
+
+ char *buf_ptr = SKIP_PACKET_TYPE (packet);
+
+ packet_length = buf_ptr - packet;
+ return 1;
+}
+
+// This method is responsible for transforming the msg from the server
+// back into a form usable by the client. Note that it reads the
+// REAL_NAME from the packet (since the server placed it there)...
+
+int
+PMC_All::decode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMC_All::decode, packet_length = %d\n",
+ packet_length));
+
+ ACE_OS::write (ACE_STDERR, packet, packet_length);
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+ char *cp = packet;
+ int remote_users = 0;
+
+ sscanf (cp,
+ "Users %d",
+ &remote_users);
+
+ this->increment_total_users (remote_users);
+
+ for (cp = (char *) ACE::strend (cp);
+ *cp != '\n';
+ cp++)
+ {
+ // Skip over the LOGIN_NAME.
+
+ char *login_name = cp;
+ char *real_name = cp = (char *) ACE::strend (cp);
+
+ for (cp = (char *) ACE::strend (cp);
+ *(cp = this->handle_protocol_entries (cp, login_name, real_name)) != '\t';
+ )
+ continue;
+ }
+
+ return 1;
+}
+
+Protocol_Record *
+PMC_All::insert_protocol_info (Protocol_Record &protocol_record)
+{
+ Protocol_Record *prp = PM_Client::insert_protocol_info (protocol_record);
+ int length = ACE_OS::strlen (prp->set_real (ACE::strnew (protocol_record.get_real ())));
+
+ if (length > this->max_key_length)
+ this->max_key_length = length;
+
+ return prp;
+}
+
+void
+PMC_All::process (void)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "remote users logged on\n"));
+ PM_Client::process ();
+}
+
+PMC_All::PMC_All (void)
+{
+}
diff --git a/ACE/apps/drwho/PMC_All.h b/ACE/apps/drwho/PMC_All.h
new file mode 100644
index 00000000000..308388adf4f
--- /dev/null
+++ b/ACE/apps/drwho/PMC_All.h
@@ -0,0 +1,37 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// PMC_All.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PMC_ALL_H
+#define _PMC_ALL_H
+
+#include "PM_Client.h"
+
+class PMC_All : public PM_Client
+{
+ // = TITLE
+ // Provides the client's lookup table abstraction for `all' users...
+
+protected:
+ virtual Protocol_Record *insert_protocol_info (Protocol_Record &protocol_record);
+ virtual int encode (char *packet, int &total_bytes);
+ virtual int decode (char *packet, int &total_bytes);
+
+public:
+ PMC_All (void);
+ virtual void process (void);
+};
+
+#endif /* _PMC_ALL_H */
diff --git a/ACE/apps/drwho/PMC_Flo.cpp b/ACE/apps/drwho/PMC_Flo.cpp
new file mode 100644
index 00000000000..b84a4528745
--- /dev/null
+++ b/ACE/apps/drwho/PMC_Flo.cpp
@@ -0,0 +1,125 @@
+// $Id$
+
+#include "Options.h"
+#include "BS_Client.h"
+#include "PMC_Flo.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_Memory.h"
+
+// This function "encodes" a list of friends by putting the userid's
+// in a contiguous block. This block can then be transmitted over to
+// the network to servers on other subnets. Several things are added
+// to make decoding easier on the other end:
+//
+// * A count of the number of friends is prepended (assumption: there
+// are no more than 9999999 friends... ;-))
+// * The login userids are separated by a single space. */
+
+int
+PMC_Flo::encode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMC_Flo::encode"));
+
+ ACE_NEW_RETURN (this->ss,
+ BS_Client,
+ -1);
+
+ SET_PACKET_TYPE (packet, Options::PROTO_FLO);
+ char *buf_ptr = SKIP_PACKET_TYPE (packet);
+
+ sprintf (buf_ptr,
+ "%d",
+ this->friend_count ());
+
+ buf_ptr += MAXUSERIDNAMELEN;
+
+ // Iterate through all the friends, copying them into the packet
+ // buffer.
+
+ for (Protocol_Record *prp; (prp = this->get_next_friend ()) != 0; )
+ buf_ptr = ACE_OS::strecpy (buf_ptr,
+ prp->get_login ());
+
+ packet_length = buf_ptr - packet;
+
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "packet_length = %d\n",
+ packet_length));
+ ACE_OS::write (ACE_STDERR, packet, packet_length);
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+
+ return 1;
+}
+
+// This method is responsible for transforming the msg from the server
+// back into a form usable by the client.
+
+int
+PMC_Flo::decode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMC_Flo::decode, packet_length = %d\n",
+ packet_length));
+ ACE_OS::write (ACE_STDERR, packet, packet_length);
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+
+ char *cp = packet;
+ int remote_users = 0;
+
+ sscanf (cp,
+ "Users %d",
+ &remote_users);
+
+ this->increment_total_users (remote_users);
+
+ for (cp = (char *) ACE::strend (cp);
+ *cp != '\n';
+ cp++)
+ {
+ char *login_name = cp;
+
+ for (cp = (char *) ACE::strend (cp);
+ *(cp = this->handle_protocol_entries (cp, login_name)) != '\t';
+)
+ continue;
+ }
+
+ return 1;
+}
+
+Protocol_Record *
+PMC_Flo::insert_protocol_info (Protocol_Record &protocol_record)
+{
+ Protocol_Record *prp = PM_Client::insert_protocol_info (protocol_record);
+ int length = ACE_OS::strlen (prp->get_real ());
+
+ if (length > this->max_key_length)
+ this->max_key_length = length;
+
+ return prp;
+}
+
+void
+PMC_Flo::process (void)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "remote friends logged on\n"));
+ PM_Client::process ();
+}
+
+PMC_Flo::PMC_Flo (void)
+{
+}
diff --git a/ACE/apps/drwho/PMC_Flo.h b/ACE/apps/drwho/PMC_Flo.h
new file mode 100644
index 00000000000..305a8d8803c
--- /dev/null
+++ b/ACE/apps/drwho/PMC_Flo.h
@@ -0,0 +1,37 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// PMC_Flo.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PMC_FLO_H
+#define _PMC_FLO_H
+
+#include "PM_Client.h"
+
+class PMC_Flo : public PM_Client
+{
+ // = TITLE
+ // Provides the client's lookup table abstraction for `flo' users...
+
+public:
+ PMC_Flo (void);
+ virtual void process (void);
+
+protected:
+ virtual Protocol_Record *insert_protocol_info (Protocol_Record &protocol_record);
+ virtual int encode (char *packet, int &total_bytes);
+ virtual int decode (char *packet, int &total_bytes);
+};
+
+#endif /* _PMC_FLO_H */
diff --git a/ACE/apps/drwho/PMC_Ruser.cpp b/ACE/apps/drwho/PMC_Ruser.cpp
new file mode 100644
index 00000000000..0a39414571c
--- /dev/null
+++ b/ACE/apps/drwho/PMC_Ruser.cpp
@@ -0,0 +1,179 @@
+// $Id$
+
+#include "global.h"
+#include "Options.h"
+#include "HT_Client.h"
+#include "PMC_Ruser.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_Memory.h"
+#include "ace/os_include/os_netdb.h"
+
+// This function is pretty much a no-op that just sets up the
+// appropriate lookup function to use.
+
+int
+PMC_Ruser::encode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMC_Ruser::encode\n"));
+
+ ACE_NEW_RETURN (this->ss,
+ HT_Client,
+ -1);
+
+ SET_PACKET_TYPE (packet, Options::PROTO_RUSER);
+
+ char *buf_ptr = SKIP_PACKET_TYPE (packet);
+
+ *buf_ptr++ = char (Options::get_opt (Options::PRINT_LOGIN_NAME));
+
+ packet_length = buf_ptr - packet;
+ return 1;
+}
+
+// This method is responsible for transforming the msg from the server
+// back into a form usable by the client. Note that it reads the
+// REAL_NAME from the packet (since the server placed it there)...
+
+int
+PMC_Ruser::decode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMC_Ruser::decode, packet_length = %d\n",
+ packet_length));
+ ACE_OS::write (ACE_STDERR, packet, packet_length);
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+ char *cp = packet;
+ int remote_users = 0;
+
+ sscanf (cp,
+ "Users %d",
+ &remote_users);
+
+ this->increment_total_users (remote_users);
+
+ for (cp = (char *) ACE::strend (cp);
+ *cp != '\n';
+ cp++)
+ {
+ char *host_name = cp;
+
+ for (cp = (char *) ACE::strend (cp);
+ *(cp = this->handle_protocol_entries (cp, host_name)) != '\t'; )
+ continue;
+ }
+
+ return 1;
+}
+
+Protocol_Record *
+PMC_Ruser::insert_protocol_info (Protocol_Record &protocol_record)
+{
+ Protocol_Record *prp = this->ss->insert (protocol_record.get_host (),
+ MAXHOSTNAMELEN);
+ Drwho_Node *current_node = protocol_record.get_drwho_list ();
+ Drwho_Node *np = this->get_drwho_node (ACE::strnnew (current_node->get_login_name (),
+ MAXUSERIDNAMELEN),
+ prp->drwho_list_);
+ int length = ACE_OS::strlen (prp->get_host ());
+
+ np->set_real_name (ACE::strnew (current_node->get_real_name ()));
+
+ if (np->get_active_count () < current_node->get_active_count ())
+ np->set_active_count (current_node->get_active_count ());
+ if (np->get_inactive_count () < current_node->get_inactive_count())
+ np->set_inactive_count (current_node->get_inactive_count ());
+
+ if (length > this->max_key_length)
+ this->max_key_length = length;
+
+ return prp;
+}
+
+char *
+PMC_Ruser::handle_protocol_entries (const char *cp,
+ const char *host_name,
+ const char *)
+{
+ static Protocol_Record protocol_record (1);
+ Drwho_Node *current_node = protocol_record.get_drwho_list ();
+
+ protocol_record.set_host (host_name);
+ current_node->set_inactive_count (ACE_OS::atoi (cp));
+ current_node->set_active_count (ACE_OS::atoi (cp = ACE_OS::strchr (cp, ' ') + 1));
+ current_node->set_login_name (cp = ACE_OS::strchr (cp, ' ') + 1);
+ current_node->set_real_name (cp = ACE_OS::strchr (cp, '\0') + 1);
+
+ this->insert_protocol_info (protocol_record);
+
+ return (char *) ACE::strend (cp);
+}
+
+void
+PMC_Ruser::process (void)
+{
+ const char *(Drwho_Node::*get_name)(void);
+
+ if (Options::get_opt (Options::PRINT_LOGIN_NAME))
+ get_name = &Drwho_Node::get_login_name;
+ else
+ get_name = &Drwho_Node::get_real_name;
+
+ for (Protocol_Record *prp;
+ (prp = this->Protocol_Manager::get_each_friend ()) != 0;
+ )
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "%-*s ",
+ this->max_key_length,
+ prp->get_host ()));
+
+ for (Drwho_Node *np = prp->get_drwho_list (); ;)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "%s",
+ (np->*get_name) ()));
+
+ if (np->get_inactive_count () != 0)
+ {
+ if (np->get_active_count () != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "*(%d)",
+ np->get_active_count ()));
+ }
+ else if (np->get_active_count () > 1)
+ ACE_DEBUG ((LM_DEBUG,
+ "*(%d)",
+ np->get_active_count ()));
+ else if (np->get_active_count () == 1)
+ ACE_DEBUG ((LM_DEBUG,
+ "*"));
+
+ np = np->next_;
+ if (np == 0)
+ break;
+ else if (Options::get_opt (Options::PRINT_LOGIN_NAME))
+ ACE_DEBUG ((LM_DEBUG,
+ " "));
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ ", "));
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+}
+
+PMC_Ruser::PMC_Ruser (void)
+{
+}
diff --git a/ACE/apps/drwho/PMC_Ruser.h b/ACE/apps/drwho/PMC_Ruser.h
new file mode 100644
index 00000000000..fe3d3c23363
--- /dev/null
+++ b/ACE/apps/drwho/PMC_Ruser.h
@@ -0,0 +1,40 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// PMC_Ruser.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PMC_RUSER_H
+#define _PMC_RUSER_H
+
+#include "PM_Client.h"
+
+class PMC_Ruser : public PM_Client
+{
+ // = TITLE
+ // Provides the client's lookup table abstraction for `ruser' users...
+
+public:
+ PMC_Ruser (void);
+ virtual void process (void);
+
+protected:
+ char *handle_protocol_entries (const char *cp,
+ const char *host_name,
+ const char * = 0);
+ Protocol_Record *insert_protocol_info (Protocol_Record &protocol_record);
+ virtual int encode (char *packet, int &total_bytes);
+ virtual int decode (char *packet, int &total_bytes);
+};
+
+#endif /* _PMC_RUSER_H */
diff --git a/ACE/apps/drwho/PMC_Usr.cpp b/ACE/apps/drwho/PMC_Usr.cpp
new file mode 100644
index 00000000000..79dc907734b
--- /dev/null
+++ b/ACE/apps/drwho/PMC_Usr.cpp
@@ -0,0 +1,117 @@
+// $Id$
+
+#include "Options.h"
+#include "SL_Client.h"
+#include "PMC_Usr.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_Memory.h"
+
+int
+PMC_Usr::encode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMC_Usr::encode"));
+
+ ACE_NEW_RETURN (this->ss,
+ SL_Client (this->usr_name),
+ -1);
+
+ SET_PACKET_TYPE (packet, Options::PROTO_USR);
+
+ char *buf_ptr = SKIP_PACKET_TYPE (packet);
+
+ buf_ptr = ACE_OS::strecpy (buf_ptr,
+ this->get_next_friend ()->get_login ());
+
+ packet_length = buf_ptr - packet;
+
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "packet_length = %d\n",
+ packet_length));
+ ACE_OS::write (ACE_STDERR, packet, packet_length);
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+ return 1;
+}
+
+// This method is responsible for transforming the msg from the server
+// back into a form usable by the client.
+
+int
+PMC_Usr::decode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMC_Usr::decode, packet_length = %d\n",
+ packet_length));
+ ACE_OS::write (ACE_STDERR, packet, packet_length);
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+
+ char *cp = packet;
+
+ if (*cp != '\n')
+ {
+ char *login_name = cp;
+
+ for (cp = (char *) ACE::strend (cp);
+ *(cp = this->handle_protocol_entries (cp, login_name)) != '\t';
+ )
+ continue;
+ }
+
+ return 1;
+}
+
+void
+PMC_Usr::process (void)
+{
+ Protocol_Record *prp = this->get_each_friend ();
+ Drwho_Node *np = prp->get_drwho_list ();
+
+ if (np == 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "<unknown>"));
+ else
+ {
+ // First try to get a login session that is active...
+
+ for (; np != 0; np = np->next_)
+ if (np->active_count_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "%s ",
+ np->get_host_name ()));
+
+ if (Options::get_opt (Options::USE_VERBOSE_FORMAT) == 0)
+ return;
+ }
+
+ for (np = prp->get_drwho_list ();
+ np != 0;
+ np = np->next_)
+ if (np->active_count_ == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "%s ",
+ np->get_host_name ()));
+
+ if (Options::get_opt (Options::USE_VERBOSE_FORMAT) == 0)
+ return;
+ }
+ }
+}
+
+PMC_Usr::PMC_Usr (char *u_name)
+ : usr_name (u_name)
+{
+}
diff --git a/ACE/apps/drwho/PMC_Usr.h b/ACE/apps/drwho/PMC_Usr.h
new file mode 100644
index 00000000000..f98c8325b83
--- /dev/null
+++ b/ACE/apps/drwho/PMC_Usr.h
@@ -0,0 +1,38 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// PMC_Usr.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PMC_USR_H
+#define _PMC_USR_H
+
+#include "PM_Client.h"
+
+class PMC_Usr : public PM_Client
+{
+ // = TITLE
+ // Provides the client's lookup table abstraction for `Usr' users...
+public:
+ PMC_Usr (char *usr_name);
+ virtual void process (void);
+
+protected:
+ virtual int encode (char *packet, int &total_bytes);
+ virtual int decode (char *packet, int &total_bytes);
+
+private:
+ char *usr_name;
+};
+
+#endif /* _PMC_USR_H */
diff --git a/ACE/apps/drwho/PMS_All.cpp b/ACE/apps/drwho/PMS_All.cpp
new file mode 100644
index 00000000000..6925c1ac772
--- /dev/null
+++ b/ACE/apps/drwho/PMS_All.cpp
@@ -0,0 +1,101 @@
+// $Id$
+
+#include "Options.h"
+#include "HT_Server.h"
+#include "PMS_All.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_pwd.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_Memory.h"
+
+// This function packs the located friends userids, plus the machines
+// they are logged into (along with the inactive and active counts on
+// each machine) into a buffer that is subsequently transmitted back
+// to the client across the network. Note that this function encodes
+// the REAL_NAME of the user in the packet.
+
+int
+PMS_All::encode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMS_All::encode"));
+
+ Protocol_Record *prp;
+ char *buf_ptr = packet;
+
+ sprintf (buf_ptr,
+ "Users %d",
+ this->get_total_users ());
+ buf_ptr += ACE_OS::strlen (buf_ptr) + 1;
+
+ // We only send back info on friends that we actually see logged in.
+
+ for (;
+ (prp = this->get_next_friend ()) != 0;
+ *buf_ptr++ = '\t')
+ buf_ptr =
+ this->handle_protocol_entries (ACE_OS::strecpy
+ (ACE_OS::strecpy (buf_ptr,
+ prp->get_login ()),
+ prp->get_real ()),
+ prp->get_drwho_list ());
+
+ *buf_ptr++ = '\n';
+ packet_length = buf_ptr - packet;
+
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "packet_length = %d\n",
+ packet_length));
+ ACE_OS::write (ACE_STDERR, packet, packet_length);
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+ return 1;
+}
+
+// This function takes a packet received from the client and calls the
+// appropriate Protocol_Manager routine to build the local table of
+// friends.
+
+int
+PMS_All::decode (char *, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMS_All::decode, packet_length = %d\n",
+ packet_length));
+
+ ACE_NEW_RETURN (this->ss,
+ HT_Server,
+ -1);
+ return 1;
+}
+
+// We only want the user's real name, not the gecos junk after the
+// first leading ','. However, if the real-name is not in the
+// password file, just return the login name instead.
+
+Protocol_Record *
+PMS_All::insert_protocol_info (Protocol_Record &protocol_record)
+{
+ Protocol_Record *prp = PM_Server::insert_protocol_info (protocol_record);
+ passwd *pwent = ACE_OS::getpwnam (prp->get_login ());
+ char *cp = (char *) ACE_OS::strchr (prp->set_real
+ (pwent == 0
+ ? prp->get_login () :
+ ACE::strnew (pwent->pw_gecos)),
+ ',');
+ if (cp != 0)
+ *cp = '\0';
+
+ return prp;
+}
+
+PMS_All::PMS_All (void)
+{
+}
diff --git a/ACE/apps/drwho/PMS_All.h b/ACE/apps/drwho/PMS_All.h
new file mode 100644
index 00000000000..41459f57cbe
--- /dev/null
+++ b/ACE/apps/drwho/PMS_All.h
@@ -0,0 +1,35 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// PMS_All.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PMS_ALL_H
+#define _PMS_ALL_H
+
+#include "PM_Server.h"
+
+class PMS_All : public PM_Server
+{
+ // = TITLE
+ // Provides the server's lookup table abstraction for `all' users...
+public:
+ PMS_All (void);
+
+protected:
+ virtual Protocol_Record *insert_protocol_info (Protocol_Record &protocol_record);
+ virtual int encode (char *packet, int &total_bytes);
+ virtual int decode (char *packet, int &total_bytes);
+};
+
+#endif /* _PMS_ALL_H */
diff --git a/ACE/apps/drwho/PMS_Flo.cpp b/ACE/apps/drwho/PMS_Flo.cpp
new file mode 100644
index 00000000000..8375ff41bc2
--- /dev/null
+++ b/ACE/apps/drwho/PMS_Flo.cpp
@@ -0,0 +1,76 @@
+// $Id$
+
+#include "Options.h"
+#include "BS_Server.h"
+#include "PMS_Flo.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_Memory.h"
+
+// This function packs the located friends userids, plus the machines
+// they are logged into (along with the inactive and active counts on
+// each machine) into a buffer that is subsequently transmitted back
+// to the client across the network.
+
+int
+PMS_Flo::encode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMS_Flo::encode"));
+
+ Protocol_Record *prp;
+ char *buf_ptr = packet;
+
+ sprintf (buf_ptr,
+ "Users %d",
+ this->get_total_users ());
+ buf_ptr += ACE_OS::strlen (buf_ptr) + 1;
+
+ // We only send back info on friends that we actually see logged in.
+
+ for (;
+ (prp = this->get_next_friend ()) != 0;
+ *buf_ptr++ = '\t')
+ buf_ptr = this->handle_protocol_entries (ACE_OS::strecpy (buf_ptr,
+ prp->get_login ()),
+ prp->get_drwho_list ());
+ *buf_ptr++ = '\n';
+ packet_length = buf_ptr - packet;
+
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "packet_length = %d\n",
+ packet_length));
+ ACE_OS::write (ACE_STDERR, packet, packet_length);
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+
+ return 1;
+}
+
+// This function takes a packet received from the client and calls the
+// appropriate Protocol_Manager routine to build the local table of
+// friends.
+
+int
+PMS_Flo::decode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMS_Flo::decode, packet_length = %d\n",
+ packet_length));
+
+ ACE_NEW_RETURN (this->ss,
+ BS_Server (packet),
+ -1);
+ return 1;
+}
+
+PMS_Flo::PMS_Flo (void)
+{
+}
diff --git a/ACE/apps/drwho/PMS_Flo.h b/ACE/apps/drwho/PMS_Flo.h
new file mode 100644
index 00000000000..b7fefa5abec
--- /dev/null
+++ b/ACE/apps/drwho/PMS_Flo.h
@@ -0,0 +1,35 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// PMS_Flo.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PMS_FLO_H
+#define _PMS_FLO_H
+
+#include "PM_Server.h"
+
+class PMS_Flo : public PM_Server
+{
+ // = TITLE
+ // Provides the server's lookup table abstraction for `flo' users...
+
+public:
+ PMS_Flo (void);
+
+protected:
+ virtual int encode (char *packet, int &total_bytes);
+ virtual int decode (char *packet, int &total_bytes);
+};
+
+#endif /* _PMS_FLO_H */
diff --git a/ACE/apps/drwho/PMS_Ruser.cpp b/ACE/apps/drwho/PMS_Ruser.cpp
new file mode 100644
index 00000000000..aa3784eb536
--- /dev/null
+++ b/ACE/apps/drwho/PMS_Ruser.cpp
@@ -0,0 +1,134 @@
+// $Id$
+
+#include "Options.h"
+#include "HT_Server.h"
+#include "PMS_Ruser.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_pwd.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_Memory.h"
+#include "ace/os_include/os_netdb.h"
+
+// This function packs the located friends userids, plus the machines
+// they are logged into (along with the inactive and active counts on
+// each machine) into a buffer that is subsequently transmitted back
+// to the client across the network. Note that this function encodes
+// the REAL_NAME of the user in the packet.
+
+int
+PMS_Ruser::encode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMS_Ruser::encode"));
+
+ Protocol_Record *prp;
+ char *buf_ptr = packet;
+
+ sprintf (buf_ptr,
+ "Users %d",
+ this->get_total_users ());
+ buf_ptr += ACE_OS::strlen (buf_ptr) + 1;
+
+ // We only send back info on hosts that we actually see.
+
+ for (;
+ (prp = this->get_next_friend ()) != 0;
+ *buf_ptr++ = '\t')
+ buf_ptr = this->handle_protocol_entries (ACE_OS::strecpy (buf_ptr,
+ prp->get_host ()),
+ prp->get_drwho_list ());
+
+ *buf_ptr++ = '\n';
+ packet_length = buf_ptr - packet;
+
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "packet_length = %d\n",
+ packet_length));
+ ACE_OS::write (ACE_STDERR, packet, packet_length);
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+ return 1;
+}
+
+// This function takes a packet received from the client and crusers
+// the appropriate Protocol_Manager routine to build the local table
+// of friends.
+
+int
+PMS_Ruser::decode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMS_Ruser::decode, packet_length = %d\n",
+ packet_length));
+
+ if (*packet)
+ Options::set_opt (Options::PRINT_LOGIN_NAME);
+
+ ACE_NEW_RETURN (this->ss,
+ HT_Server,
+ -1);
+ return 1;
+}
+
+Protocol_Record *
+PMS_Ruser::insert_protocol_info (Protocol_Record &protocol_record)
+{
+ Drwho_Node *current_node = protocol_record.get_drwho_list ();
+ Protocol_Record *prp = this->ss->insert (current_node->get_host_name (),
+ MAXHOSTNAMELEN);
+ Drwho_Node *np = this->get_drwho_node (ACE::strnnew (protocol_record.get_login (),
+ MAXUSERIDNAMELEN),
+ prp->drwho_list_);
+
+ if (Options::get_opt (Options::PRINT_LOGIN_NAME))
+ np->set_real_name ("");
+ else
+ {
+ passwd *pwent = ACE_OS::getpwnam (np->get_login_name ());
+ char *cp =
+ (char *) ACE_OS::strchr (np->set_real_name (pwent == 0
+ ? np->get_login_name ()
+ : ACE::strnew (pwent->pw_gecos)),
+ ',');
+ if (cp != 0)
+ *cp = '\0';
+ }
+
+ if (current_node->get_idle_time () >= MAX_USER_TIMEOUT)
+ np->inactive_count_++;
+ else
+ np->active_count_++;
+
+ return prp;
+}
+
+char *
+PMS_Ruser::handle_protocol_entries (char *buf_ptr,
+ Drwho_Node *np)
+{
+ for (; np != 0; np = np->next_)
+ {
+ sprintf (buf_ptr,
+ "%d %d ",
+ np->get_inactive_count (),
+ np->get_active_count ());
+ buf_ptr += ACE_OS::strlen (buf_ptr);
+
+ buf_ptr = ACE_OS::strecpy (ACE_OS::strecpy (buf_ptr,
+ np->get_login_name ()),
+ np->get_real_name ());
+ }
+
+ return buf_ptr;
+}
+
+PMS_Ruser::PMS_Ruser (void)
+{
+}
diff --git a/ACE/apps/drwho/PMS_Ruser.h b/ACE/apps/drwho/PMS_Ruser.h
new file mode 100644
index 00000000000..f26e916549f
--- /dev/null
+++ b/ACE/apps/drwho/PMS_Ruser.h
@@ -0,0 +1,37 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// PMS_Ruser.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PMS_RUSER_H
+#define _PMS_RUSER_H
+
+#include "PM_Server.h"
+
+class PMS_Ruser : public PM_Server
+{
+ // = TITLE
+ // Provides the server's lookup table abstraction for `ruser' users...
+
+public:
+ PMS_Ruser (void);
+
+protected:
+ virtual char *handle_protocol_entries (char *bp, Drwho_Node *hp);
+ virtual Protocol_Record *insert_protocol_info (Protocol_Record &protocol_record);
+ virtual int encode (char *packet, int &total_bytes);
+ virtual int decode (char *packet, int &total_bytes);
+};
+
+#endif /* _PMS_RUSER_H */
diff --git a/ACE/apps/drwho/PMS_Usr.cpp b/ACE/apps/drwho/PMS_Usr.cpp
new file mode 100644
index 00000000000..ac8da582cc4
--- /dev/null
+++ b/ACE/apps/drwho/PMS_Usr.cpp
@@ -0,0 +1,83 @@
+// $Id$
+
+#include "Options.h"
+#include "SL_Server.h"
+#include "PMS_Usr.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_Memory.h"
+
+// This function "encodes" a list of friends by putting the userid's in
+// a contiguous block. This block can then be transmitted over to the
+// network to servers on other subnets. Several things are added to
+// make decoding easier on the other end:
+//
+// * A count of the number of friends is prepended (assumption: there
+// are no more than 9999999 friends... ;-))
+// * The login userids are separated by a single space. */
+
+int
+PMS_Usr::encode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMS_Usr::encode"));
+
+ char *buf_ptr = packet;
+
+ // We only send back info on friend that is actually logged in.
+
+ Protocol_Record *prp = this->get_next_friend ();
+
+ if (prp)
+ {
+ buf_ptr = this->handle_protocol_entries (ACE_OS::strecpy (buf_ptr,
+ prp->get_login ()),
+ prp->get_drwho_list ());
+ *buf_ptr++ = '\t';
+ }
+
+ *buf_ptr++ = '\n';
+ packet_length = buf_ptr - packet;
+
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "packet_length = %d\n",
+ packet_length));
+ ACE_OS::write (ACE_STDERR, packet, packet_length);
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+
+ return 1;
+}
+
+// This function takes a packet received from the client and calls the
+// appropriate Protocol_Manager routine to build the local table of
+// friends.
+
+int
+PMS_Usr::decode (char *packet, int &packet_length)
+{
+ if (Options::get_opt (Options::DEBUG) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "in PMS_Usr::decode, packet_length = %d\n",
+ packet_length));
+ ACE_OS::write (ACE_STDERR, packet, packet_length);
+ ACE_DEBUG ((LM_DEBUG,
+ "\n"));
+ }
+
+ ACE_NEW_RETURN (this->ss,
+ SL_Server (packet),
+ -1);
+ return 1;
+}
+
+PMS_Usr::PMS_Usr (void)
+{
+}
diff --git a/ACE/apps/drwho/PMS_Usr.h b/ACE/apps/drwho/PMS_Usr.h
new file mode 100644
index 00000000000..1f29e43d653
--- /dev/null
+++ b/ACE/apps/drwho/PMS_Usr.h
@@ -0,0 +1,35 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// PMS_Usr.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PMS_USR_H
+#define _PMS_USR_H
+
+#include "PM_Server.h"
+
+class PMS_Usr : public PM_Server
+{
+ // = TITLE
+ // Provides the client's lookup table abstraction for `Usr' users...
+
+public:
+ PMS_Usr (void);
+
+protected:
+ virtual int encode (char *packet, int &total_bytes);
+ virtual int decode (char *packet, int &total_bytes);
+};
+
+#endif /* _PMS_USR_H */
diff --git a/ACE/apps/drwho/PM_Client.cpp b/ACE/apps/drwho/PM_Client.cpp
new file mode 100644
index 00000000000..216cb6e5368
--- /dev/null
+++ b/ACE/apps/drwho/PM_Client.cpp
@@ -0,0 +1,140 @@
+// $Id$
+
+#include "Options.h"
+#include "PM_Server.h"
+#include "PM_Client.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_stdlib.h"
+
+// This function is used to merge the LOGIN_NAME from server HOST_NAME
+// into the userids kept on the client's side. Note that we must
+// allocate memory for HOST_NAME...
+
+Protocol_Record *
+PM_Client::insert_protocol_info (Protocol_Record &protocol_record)
+{
+ Protocol_Record *prp = this->ss->insert (protocol_record.get_login ());
+ Drwho_Node *current_node = protocol_record.get_drwho_list ();
+ Drwho_Node *np = this->get_drwho_node (ACE::strnew (current_node->get_host_name ()),
+ prp->drwho_list_);
+
+ // Update the active and inactive counts.
+
+ if (np->get_active_count () < current_node->get_active_count ())
+ {
+ np->set_active_count (current_node->get_active_count ());
+ prp->is_active_ = 1;
+ }
+
+ if (np->get_inactive_count () < current_node->get_inactive_count())
+ np->set_inactive_count (current_node->get_inactive_count ());
+
+ return prp;
+}
+
+// This routine does all the dirty work, and actually prints out the
+// friends info in a nicely formatted manner.
+
+void
+PM_Client::process (void)
+{
+ const char *(Protocol_Record::*get_name)(void);
+
+ if (Options::get_opt (Options::PRINT_LOGIN_NAME))
+ get_name = &Protocol_Record::get_login;
+ else
+ get_name = &Protocol_Record::get_real;
+
+ int active_friends = 0;
+ int users = this->Protocol_Manager::get_total_users ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "------------------------\n"));
+
+ if (Options::get_opt (Options::PRINT_LOGIN_NAME))
+ this->max_key_length = MAXUSERIDNAMELEN;
+
+ // Goes through the queue of all the logged in friends and prints
+ // out the associated information.
+
+ for (Protocol_Record *prp = this->Protocol_Manager::get_each_friend ();
+ prp != 0;
+ prp = this->Protocol_Manager::get_each_friend ())
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "%c%-*s [", (prp->is_active_ != 0 ? '*' : ' '),
+ this->max_key_length,
+ (prp->*get_name) ()));
+
+ for (Drwho_Node *np = prp->get_drwho_list (); ;)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ np->get_host_name (),
+ stdout));
+
+ active_friends += np->get_active_count ();
+
+ if (np->get_inactive_count () != 0)
+ {
+ if (np->get_active_count () != 0)
+ ACE_DEBUG ((LM_DEBUG,
+ "*(%d)",
+ np->get_active_count ()));
+ }
+ else if (np->get_active_count () > 1)
+ ACE_DEBUG ((LM_DEBUG,
+ "*(%d)",
+ np->get_active_count ()));
+ else if (np->get_active_count () == 1)
+ ACE_DEBUG ((LM_DEBUG,
+ "*"));
+
+ np = np->next_;
+ if (np == 0)
+ break;
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ " "));
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ "]\n"));
+ }
+
+ ACE_DEBUG ((LM_DEBUG,
+ "------------------------\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ "friends: %d\tusers: %d\n",
+ active_friends,
+ users));
+}
+
+char *
+PM_Client::handle_protocol_entries (const char *cp,
+ const char *login_name,
+ const char *real_name)
+{
+ static Protocol_Record protocol_record (1);
+ Drwho_Node *current_node = protocol_record.get_drwho_list ();
+
+ protocol_record.set_login (login_name);
+ protocol_record.set_real (real_name);
+ current_node->set_inactive_count (ACE_OS::atoi (cp));
+ current_node->set_active_count (ACE_OS::atoi (cp = ACE_OS::strchr (cp, ' ') + 1));
+ current_node->set_host_name (cp = ACE_OS::strchr (cp, ' ') + 1);
+
+ this->insert_protocol_info (protocol_record);
+
+ return (char *) ACE::strend (cp);
+}
+
+PM_Client::PM_Client (void)
+ : max_key_length (0)
+{
+}
+
+PM_Client::~PM_Client (void)
+{
+}
diff --git a/ACE/apps/drwho/PM_Client.h b/ACE/apps/drwho/PM_Client.h
new file mode 100644
index 00000000000..f44ab84f69f
--- /dev/null
+++ b/ACE/apps/drwho/PM_Client.h
@@ -0,0 +1,45 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// PM_Client.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PM_CLIENT_H
+#define _PM_CLIENT_H
+
+#include "Protocol_Manager.h"
+
+class PM_Client : public Protocol_Manager
+{
+ // = TITLE
+ // Provides the client side of the friend manager lookup table abstraction.
+public:
+ PM_Client (void);
+ virtual ~PM_Client (void);
+
+ virtual int encode (char *packet, int &total_bytes) = 0;
+ virtual int decode (char *packet, int &total_bytes) = 0;
+ virtual void process (void);
+
+protected:
+ int max_key_length;
+
+ virtual char *handle_protocol_entries (const char *cp,
+ const char *key_name1,
+ const char *key_name2 = 0);
+
+ virtual Protocol_Record *insert_protocol_info (Protocol_Record &protocol_record);
+};
+
+#endif /* _PM_CLIENT_H */
+
diff --git a/ACE/apps/drwho/PM_Server.cpp b/ACE/apps/drwho/PM_Server.cpp
new file mode 100644
index 00000000000..88a32b586c6
--- /dev/null
+++ b/ACE/apps/drwho/PM_Server.cpp
@@ -0,0 +1,83 @@
+// $Id$
+
+#include "Options.h"
+#include "Rwho_DB_Manager.h"
+#include "PM_Server.h"
+#include "ace/ACE.h"
+#include "ace/OS_NS_string.h"
+
+// This is the main method for the server side of things. It reads
+// the RWHO file on the local machine and inserts HOST_NAME
+// information for each LOGIN_NAME that is a friend into the
+// DRWHO_LIST. This function is also responsible for determining
+// whether a given LOGIN_NAME is currently idle or not.
+
+int
+PM_Server::process (void)
+{
+ RWho_DB_Manager ru;
+ Protocol_Record protocol_record (1);
+
+ while (ru.get_next_user (protocol_record) > 0)
+ this->insert_protocol_info (protocol_record);
+
+ return 1;
+}
+
+// Insert the HOST_NAME into the server's lookup table on behalf of
+// user LOGIN_NAME. Note that we need to allocate memory for
+// HOST_NAME...
+
+Protocol_Record *
+PM_Server::insert_protocol_info (Protocol_Record &protocol_record)
+{
+ Protocol_Record *prp = this->ss->insert (protocol_record.get_login ());
+
+ Drwho_Node *current_node = protocol_record.get_drwho_list ();
+
+ if (current_node->get_idle_time () < MAX_USER_TIMEOUT)
+ this->increment_total_users ();
+
+ if (prp)
+ {
+ Drwho_Node *np =
+ this->get_drwho_node (ACE::strnew (current_node->get_host_name ()),
+ prp->drwho_list_);
+
+ if (current_node->get_idle_time () >= MAX_USER_TIMEOUT)
+ np->inactive_count_++;
+ else
+ np->active_count_++;
+ }
+
+ return prp;
+}
+
+// Put the inactive and active counts, plus the hostname into the
+// packet.
+
+char *
+PM_Server::handle_protocol_entries (char *buf_ptr,
+ Drwho_Node *np)
+{
+
+ for (; np != 0; np = np->next_)
+ {
+ sprintf (buf_ptr,
+ "%d %d %s",
+ np->get_inactive_count (),
+ np->get_active_count (),
+ np->get_host_name ());
+ buf_ptr += ACE_OS::strlen (buf_ptr) + 1;
+ }
+
+ return buf_ptr;
+}
+
+PM_Server::PM_Server (void)
+{
+}
+
+PM_Server::~PM_Server (void)
+{
+}
diff --git a/ACE/apps/drwho/PM_Server.h b/ACE/apps/drwho/PM_Server.h
new file mode 100644
index 00000000000..2a355c8e262
--- /dev/null
+++ b/ACE/apps/drwho/PM_Server.h
@@ -0,0 +1,41 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// PM_Server.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PM_SERVER_H
+#define _PM_SERVER_H
+
+#include "Protocol_Manager.h"
+
+class PM_Server : public Protocol_Manager
+{
+ // = TITLE
+ // Handle the server's lookup table abstraction.
+
+public:
+ PM_Server (void);
+ virtual ~PM_Server (void);
+
+ virtual int encode (char *packet, int &total_bytes) = 0;
+ virtual int decode (char *packet, int &total_bytes) = 0;
+ virtual int process (void);
+
+protected:
+ virtual char *handle_protocol_entries (char *bp,
+ Drwho_Node *hp);
+ virtual Protocol_Record *insert_protocol_info (Protocol_Record &protocol_record);
+};
+
+#endif /* _PM_SERVER_H */
diff --git a/ACE/apps/drwho/Protocol_Manager.cpp b/ACE/apps/drwho/Protocol_Manager.cpp
new file mode 100644
index 00000000000..5e93399c837
--- /dev/null
+++ b/ACE/apps/drwho/Protocol_Manager.cpp
@@ -0,0 +1,88 @@
+// $Id$
+
+#include "ace/config-all.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_Memory.h"
+#include "ace/OS_NS_string.h"
+
+#include "Options.h"
+#include "Protocol_Manager.h"
+
+// Returns a pointer to the Drwho_Node associated with HOST_NAME (if
+// it exists, otherwise a new node is created. Note that if a
+// Drwho_Node is found it is moved to the front of the list so that
+// subsequent finds are faster (i.e., self-organizing!)
+
+Drwho_Node *
+Protocol_Manager::get_drwho_node (char *key_name, Drwho_Node *&head)
+{
+ Drwho_Node **temp = &head;
+ for (; *temp != 0; temp = &(*temp)->next_)
+ if (ACE_OS::strcmp (key_name,
+ (*temp)->get_login_name ()) == 0)
+ break;
+
+ if (*temp == 0)
+ ACE_NEW_RETURN (head,
+ Drwho_Node (key_name, head),
+ 0);
+ else
+ {
+ Drwho_Node *t = *temp;
+
+ *temp = (*temp)->next_;
+ t->next_ = head;
+
+ head = t;
+ }
+
+ return head;
+}
+
+Protocol_Manager::Protocol_Manager (void)
+ : total_users (0)
+{
+}
+
+Protocol_Manager::~Protocol_Manager (void)
+{
+ if (Options::get_opt (Options::DEBUG))
+ ACE_DEBUG ((LM_DEBUG,
+ "disposing Protocol_Manager\n"));
+}
+
+// Returns the next friend in the sequence of sorted friends.
+
+Protocol_Record *
+Protocol_Manager::get_next_friend (void)
+{
+ return this->ss->get_next_entry ();
+}
+
+Protocol_Record *
+Protocol_Manager::get_each_friend (void)
+{
+ return this->ss->get_each_entry ();
+}
+
+// Returns the number of friends.
+
+int
+Protocol_Manager::friend_count (void)
+{
+ return this->ss->n_elems ();
+}
+
+// Returns total number of users logged in throughout the system.
+
+int
+Protocol_Manager::get_total_users (void)
+{
+ return Protocol_Manager::total_users;
+}
+
+void
+Protocol_Manager::increment_total_users (int remote_users)
+{
+ Protocol_Manager::total_users += remote_users;
+}
diff --git a/ACE/apps/drwho/Protocol_Manager.h b/ACE/apps/drwho/Protocol_Manager.h
new file mode 100644
index 00000000000..fd4ef92a9ed
--- /dev/null
+++ b/ACE/apps/drwho/Protocol_Manager.h
@@ -0,0 +1,58 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// Protocol_Manager.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PROTOCOL_MANAGER_H
+#define _PROTOCOL_MANAGER_H
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "Options.h"
+#include "Search_Struct.h"
+#include "Protocol_Record.h"
+
+class Protocol_Manager
+{
+ // = TITLE
+ // A base class that consolidates friend management functionality
+ // shared by both clients and servers.
+public:
+ Protocol_Manager (void);
+ virtual ~Protocol_Manager (void);
+
+ virtual int encode (char *packet, int &total_bytes) = 0;
+ virtual int decode (char *packet, int &total_bytes) = 0;
+
+protected:
+ int total_users;
+ Search_Struct *ss;
+
+ int friend_count (void);
+
+ Drwho_Node *get_drwho_node (char *host_name, Drwho_Node *&head);
+ int get_total_users (void);
+ void increment_total_users (int remote_users = 1);
+
+ Protocol_Record *get_next_friend (void);
+ Protocol_Record *get_each_friend (void);
+
+ virtual Protocol_Record *insert_protocol_info (Protocol_Record &protocol_record) = 0;
+};
+
+#endif /* _PROTOCOL_MANAGER_H */
diff --git a/ACE/apps/drwho/Protocol_Record.cpp b/ACE/apps/drwho/Protocol_Record.cpp
new file mode 100644
index 00000000000..a04454e51bb
--- /dev/null
+++ b/ACE/apps/drwho/Protocol_Record.cpp
@@ -0,0 +1,97 @@
+// $Id$
+
+#include "Options.h"
+#include "Protocol_Record.h"
+#include "ace/Log_Msg.h"
+
+// Static initialization.
+
+Drwho_Node Protocol_Record::drwho_node_;
+
+Protocol_Record::~Protocol_Record (void)
+{
+ if (Options::get_opt (Options::DEBUG))
+ ACE_DEBUG ((LM_DEBUG,
+ "disposing Protocol_Record\n"));
+
+ for (Drwho_Node *np = this->get_drwho_list ();
+ np != 0; )
+ {
+ Drwho_Node *t = np;
+ np = np->next_;
+ delete t;
+ }
+}
+
+Protocol_Record::Protocol_Record (void)
+ : key_name1_ (0),
+ key_name2_ (0),
+ drwho_list_ (0),
+ next_ (0),
+ is_active_ (0)
+{
+}
+
+Protocol_Record::Protocol_Record (int)
+ : key_name1_ (0),
+ key_name2_ (0),
+ drwho_list_ (&Protocol_Record::drwho_node_),
+ next_ (0),
+ is_active_ (0)
+{
+}
+
+Protocol_Record::Protocol_Record (const char *kn1,
+ Protocol_Record *next)
+ : key_name1_ (kn1),
+ key_name2_ (0),
+ drwho_list_ (0),
+ next_ (next),
+ is_active_ (0)
+{
+}
+
+const char *
+Protocol_Record::get_login (void)
+{
+ return this->key_name1_;
+}
+
+const char *
+Protocol_Record::set_login (const char *str)
+{
+ this->key_name1_ = str;
+ return str;
+}
+
+const char *
+Protocol_Record::get_real (void)
+{
+ return this->key_name2_;
+}
+
+const char *
+Protocol_Record::get_host (void)
+{
+ return this->key_name1_;
+}
+
+const char *
+Protocol_Record::set_host (const char *str)
+{
+ this->key_name1_ = str;
+ return str;
+}
+
+const char *
+Protocol_Record::set_real (const char *str)
+{
+ this->key_name2_ = str;
+ return str;
+}
+
+Drwho_Node *
+Protocol_Record::get_drwho_list (void)
+{
+ return this->drwho_list_;
+}
diff --git a/ACE/apps/drwho/Protocol_Record.h b/ACE/apps/drwho/Protocol_Record.h
new file mode 100644
index 00000000000..60cf250adf1
--- /dev/null
+++ b/ACE/apps/drwho/Protocol_Record.h
@@ -0,0 +1,49 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// Protocol_Record.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _PROTOCOL_RECORD_H
+#define _PROTOCOL_RECORD_H
+
+#include "Drwho_Node.h"
+
+class Protocol_Record
+{
+ // = TITLE
+ // Stores information about a single friend's status.
+
+public:
+ Protocol_Record (void);
+ Protocol_Record (int use_dummy);
+ Protocol_Record (const char *key_name1,
+ Protocol_Record *next = 0);
+ ~Protocol_Record (void);
+ const char *get_host (void);
+ const char *set_host (const char *str);
+ const char *get_login (void);
+ const char *set_login (const char *str);
+ const char *get_real (void);
+ const char *set_real (const char *str);
+ Drwho_Node *get_drwho_list (void);
+
+ static Drwho_Node drwho_node_;
+ const char *key_name1_;
+ const char *key_name2_;
+ Drwho_Node *drwho_list_;
+ Protocol_Record *next_;
+ int is_active_;
+};
+
+#endif /* _PROTOCOL_RECORD_H */
diff --git a/ACE/apps/drwho/README b/ACE/apps/drwho/README
new file mode 100644
index 00000000000..af1c4b401c7
--- /dev/null
+++ b/ACE/apps/drwho/README
@@ -0,0 +1,308 @@
+This directory contains the "distributed rwho" (drwho) program. Drwho
+alleviates certain rwho(1) limitations. For instance it adds
+functionality that spans subnets. In addition, drwho prints a much
+more concise listing of who's logged in around a network.
+
+Below are some examples of how to use drwho.
+
+0. Start by running the server in a window or as a daemon, e.g., run
+ the following on a local machine, such as tango.cs.wustl.edu:
+
+% drwho-server
+
+Then, If you'd like to find out who's logged in, try the following
+commands:
+
+1. Print out the command-line options.
+
+% drwho-client -h
+usage: ./drwho-client
+-? prints a short usage message
+-A append the following hostname to the list of predefined hostnames.
+-a return information on *all* users remotely logged in (uses yp passwd).
+-b run the server in the background (i.e., as a daemon).
+-d turn on debugging.
+-F use the following file contents to initialize the host list.
+-f use the following file contents to initialize the friends database.
+-H use the following hostname as part of the new list of hostnames.
+ (this option overwrites the existing default names).
+-h print a long usage message.
+-L print the login name rather than the real name (which is the default).
+-l print information in long format (works for all protocols).
+-p set the port number (server must correspond).
+-r do the remote lookups (i.e., local operations are the default).
+-R print info using the rusers format.
+-s sort the output by login name.
+-S sort the output by real name.
+-t set the amount of time we wait for servers to timeout.
+-w return information on just one user.
+
+----------------------------------------
+
+2. Find out which friends are logged in (* means currently active)
+
+% drwho-client -A tango.cs.wustl.edu -r -f ~schmidt/.friends.dta
+remote friends logged on
+------------------------
+*Doug O'las [tango*(3) mambo]
+ Carlos O'Ryan [tango swarm.cs.wustl.edu macarena]
+ Irfan Pyarali [merengue]
+ Nanbor Wang [lambada]
+ Marina Spivak [mambo]
+ Chris Gill [tango]
+*Vishal [merengue*(2)]
+ Kirthika [tango waltz]
+ Naga [tango polka]
+ Alex [lindy]
+ Bala [cumbia]
+ Pradeep [flamenco]
+ Matt Braun [lambada]
+------------------------
+friends: 5 users: 168
+
+You'll to write a friends.dta file in order for this feature to work.
+Here's one that I've got:
+
+schmidt Doug O'las
+coryan Carlos O'Ryan
+irfan Irfan Pyarali
+levine David Levine
+nanbor Nanbor Wang
+jp4 Jeff Parsons
+marina Marina Spivak
+cdgill Chris Gill
+vishal Vishal
+kirthika Kirthika
+naga Naga
+alex Alex
+bala Bala
+pradeep Pradeep
+brunsch Darrell Brunsch
+jxh James Hu
+yamuna Yamuna
+mjb2 Matt Braun
+gokhale Andy Gokhale
+fredk Fred Kuhns
+
+If you put this file in ~/.friends.dta drwho will automatically locate
+it.
+
+----------------------------------------
+
+3. Find out where a particular person is logged in:
+
+% drwho-client -A tango.cs.wustl.edu -r -w schmidt
+tango
+
+This is useful for remote commands that require a hostname, e.g.:
+
+% talk schmidt@`drwho-client -A tango.cs.wustl.edu -r -w schmidt`
+
+or
+
+% rsh `drwho-client -w schmidt` ps
+ PID TTY TIME CMD
+ 1844 pts/9 0:01 tcsh_6.0
+ 4821 ? 0:02 perfmete
+ 77 pts/20 0:01 tcsh_6.0
+ 4845 pts/2 0:00 tcsh_6.0
+ 4766 ? 0:00 xmessage
+ 4850 pts/3 0:06 tcsh_6.0
+ 5057 pts/4 0:01 tcsh_6.0
+ 4826 ? 18:07 netscape
+ 4802 ? 0:07 mwm
+% foreach host (`drwho -r -l -w schmidt`)
+? echo $host
+? rsh $host w | egrep schmidt
+? end
+
+----------------------------------------
+
+4. Find out everyone who is logged in everywhere!
+
+% drwho-client -A tango.cs.wustl.edu -r -a
+remote users logged on
+------------------------
+ rlneblet [ascc]
+ woody [fixer]
+ Jyoti Parwatikar [hopscotch]
+ Stephen D. Scott [occam]
+ klkramer [ascc]
+ dmorris [ascc]
+*pabacard [ascc*]
+ sestasne [ascc]
+ Sumedh Mungee [merengue lindy]
+ Alexander Babu Arulanthu [lindy]
+ Robert A. Rouse [siesta]
+ asamarak [ascc]
+ Tom Chaney [snoodles]
+ Joe Hoffert [monkeybars]
+ ircornel [ascc]
+ Chris Cleeland [macarena]
+*Matthew Karl Lundberg [enz lcs*(2)]
+ dmschult [ascc]
+ sherlia [owen]
+*wmwhites [ascc*]
+ Marius Mihai Tutunaru [siesta]
+ Ken Wong [ackbar sarlacc]
+ abstutts [ascc]
+ Barry L. Kalman [sachel]
+ Yunhong Zhou [siesta]
+ Marina Igorevna Spivak [mambo]
+ mschraed [ascc]
+ tuck [ascc]
+ Daniel Robert Dooly [cardinal]
+ emlentz [ascc]
+ Margaret Flucke [honker yoda brainmap]
+ Jonathan S. Pollack [siesta]
+ Gurudatta M. Parulkar [ackbar]
+ Mike Richards [teebo]
+*Vishal Kachroo [merengue*(1)]
+ The dump man [tapeworm]
+ Uooyeol Yoon [siesta]
+ jtlink [ascc]
+ Dan Rosenstein [tubman]
+ cdnorden [ascc]
+ Jon Turner [spanky]
+ Stan C. Kwasny [lambda]
+ aymessin [ascc]
+ Nanbor Wang [lambada]
+ wolf [sarlacc]
+ jgbers [ascc]
+ Pradeep Gore [flamenco]
+ Chris D. Gill [tango]
+ sduseja [ascc]
+ amgarcia [ascc]
+*Hongyin Quan [ackbar*(2)]
+ firemen [helen]
+*lskafenb [ascc*]
+ Sally Goldman [occam]
+ Marcel Waldvogel [tiger]
+ klforesm [ascc]
+ Andy Fingerhut [yoda leia]
+ root@tango [tango emperor siren flora helen boushi tapeworm siesta rainier taumsauk honker polka]
+ Nagarajan Surendran [tango polka]
+ ajeckste [ascc]
+ Linda Suri [kavita]
+ Sarah Elizabeth Burcham [helen]
+ Salathiel Sawyer [helen]
+ A. Maynard Engebretson [wicket]
+ Theresa Manzara [siesta]
+ aagrillo [ascc]
+ ksviehen [ascc]
+ Will Gillett [gel]
+ Elaine M Ashton [helen]
+ James C. Gray [siesta]
+ Ian Flanigan [siesta]
+ jacrank [ascc]
+ Matthew J Braun [lambada]
+*pjhanrah [ascc*]
+ Vadim Adamov [siesta]
+*rbherrin [ascc*]
+ kslee [ascc]
+ Balachandran Natarajan [cumbia]
+*Qianbo Huai [ecommerce*(2)]
+ Scott Thomas Haug [bacon kato]
+ Yuhua Chen [beru]
+ blawrenc [ascc]
+ dcoats [ascc]
+*sdsinger [ascc*]
+ Katherine Skirving Larson [odysseus mas]
+ rmcarbon [ascc]
+ rer [luke honker leia]
+ Ron Loui [ai siesta]
+ Sergio Flores [tango siesta]
+ maint [helen]
+ mewedeha [ascc]
+ Scott Simon [ackbar]
+ weathert [anakin hobbie honker]
+ Kirthika Parameswaran [waltz tango]
+ Scott Douglas Powers [greedo buster]
+*vehays [ascc*]
+ Multiagent Systems Research Group [siren]
+*Douglas C. Schmidt [tango*(3) mambo]
+ sunyh [r2d2]
+*jbbrooks [ascc*]
+ mweisema [ascc]
+*baruethe [ascc*]
+ Yan Zhou [thunderball]
+*jennyc [ascc*]
+ Karl Stiefvater [tamarin helen]
+ John Roman [helen]
+ slstraus [ascc]
+ Subhash Suri [kavita]
+ Sandeep Sikka [siesta]
+ Dna Mutants [lcs]
+ Irfan Pyarali [merengue]
+ ajhingst [ascc]
+ Tuomas Sandholm [siren]
+ Carlos O'Ryan [tango swarm.cs.wustl.edu macarena]
+ Tilman Wolf [siesta]
+------------------------
+friends: 20 users: 20
+
+----------------------------------------
+
+5. Print out all machines and who is logged into each one
+
+% drwho-client -A tango.cs.wustl.edu -R -l
+kavita Subhash Suri, Linda Suri
+lcs Matthew Karl Lundberg*(2), Dna Mutants
+leia Andy Fingerhut, rer
+rainier root@tango
+thunderball Yan Zhou
+lindy Sumedh Mungee, Alexander Babu Arulanthu
+flamenco Pradeep Gore
+ai Ron Loui
+wicket A. Maynard Engebretson
+occam Stephen D. Scott, Sally Goldman
+helen firemen, Sarah Elizabeth Burcham, Elaine M Ashton, root@tango, maint, John Roman, Karl Stiefvater, Salathiel Sawyer
+enz Matthew Karl Lundberg
+tamarin Karl Stiefvater
+tiger Marcel Waldvogel
+cumbia Balachandran Natarajan
+r2d2 sunyh
+fixer woody
+ecommerce Qianbo Huai*(2)
+lambda Stan C. Kwasny
+boushi root@tango
+mambo Douglas C. Schmidt, Marina Igorevna Spivak
+ascc slstraus, rmcarbon, aymessin, aagrillo, sdsinger*, dmschult, sestasne, dmorris, jgbers, jennyc*, sduseja, baruethe*, gzhou*, vehays*, pjhanrah*, dcoats, saduthie*, ksviehen, cdnorden, ajhingst*, mschraed, asamarak, pabacard*, mewedeha, ajeckste, jbbrooks, blawrenc, amgarcia, abstutts, klforesm, klkramer, pkshah*, jtlink, jacrank, wmwhites*, kslee, mweisema, emlentz, rlneblet, tuck
+beru Yuhua Chen
+emperor root@tango
+siren Tuomas Sandholm, root@tango, Multiagent Systems Research Group
+tubman Dan Rosenstein
+gel Will Gillett
+honker Margaret Flucke, root@tango, weathert, rer
+greedo Scott Douglas Powers
+swarm.cs.wustl.edu Carlos O'Ryan
+tapeworm root@tango, The dump man
+siesta Uooyeol Yoon, Marius Mihai Tutunaru, Vadim Adamov, Robert A. Rouse, Jonathan S. Pollack, James C. Gray, Sergio Flores, Sandeep Sikka, Ron Loui, Yunhong Zhou, Tilman Wolf, Theresa Manzara, Ian Flanigan, root@tango
+luke rer
+snoodles Tom Chaney
+ackbar Ken Wong, Scott Simon, Gurudatta M. Parulkar, Hongyin Quan*(1)
+buster Scott Douglas Powers
+tango Nagarajan Surendran, Sergio Flores, Chris D. Gill, Kirthika Parameswaran, Carlos O'Ryan, root@tango, Douglas C. Schmidt*(3)
+teebo Mike Richards
+cardinal Daniel Robert Dooly
+lambada Nanbor Wang, Matthew J Braun
+merengue Sumedh Mungee, Vishal Kachroo*(1), Irfan Pyarali
+macarena Chris Cleeland, Carlos O'Ryan
+sarlacc wolf, Ken Wong
+spanky Jon Turner
+brainmap Margaret Flucke
+polka Nagarajan Surendran, root@tango
+waltz Kirthika Parameswaran
+flora root@tango
+anakin weathert
+bacon Scott Thomas Haug
+hopscotch Jyoti Parwatikar
+mas Katherine Skirving Larson
+kato Scott Thomas Haug
+hobbie weathert
+odysseus Katherine Skirving Larson
+sachel Barry L. Kalman
+taumsauk root@tango
+yoda Margaret Flucke, Andy Fingerhut
+owen sherlia
+monkeybars Joe Hoffert
diff --git a/ACE/apps/drwho/Rwho_DB_Manager.cpp b/ACE/apps/drwho/Rwho_DB_Manager.cpp
new file mode 100644
index 00000000000..cd437bfd407
--- /dev/null
+++ b/ACE/apps/drwho/Rwho_DB_Manager.cpp
@@ -0,0 +1,126 @@
+// $Id$
+#include "global.h"
+#include "Options.h"
+#include "Rwho_DB_Manager.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/OS_NS_time.h"
+#include "ace/OS_NS_fcntl.h"
+
+// Change to the RWHO directory to speed up and simplify later
+// processing. This requires opening the directory for reading with
+// the directory iterator abstraction and then skipping the first two
+// files in the directory, which are assumed to be "." and ".." (this
+// function needs to be changed if this assumption does not hold!)
+
+RWho_DB_Manager::RWho_DB_Manager (void)
+ : number_of_users (0),
+ current_user (0),
+ WHOD_HEADER_SIZE (sizeof host_data - sizeof host_data.wd_we),
+ rwho_dir_name (RWHODIR)
+{
+ if (ACE_OS::getcwd (this->original_pathname, MAXPATHLEN + 1) == 0)
+ ACE_ERROR ((LM_ERROR,
+ "%p\n%a",
+ Options::program_name,
+ 1));
+
+ if (ACE_OS::chdir (this->rwho_dir_name) < 0)
+ ACE_ERROR ((LM_ERROR,
+ "%p\n%a",
+ this->rwho_dir_name,
+ 1));
+
+ this->rwho_dir.open (this->rwho_dir_name);
+
+#if 0
+ // Skip "." and ".."
+ this->rwho_dir.read ();
+ this->rwho_dir.read ();
+#endif
+}
+
+// The destructor cleans up the RWHOD_DIR handle.
+
+RWho_DB_Manager::~RWho_DB_Manager (void)
+{
+ if (ACE_OS::chdir (this->original_pathname) < 0)
+ ACE_ERROR ((LM_ERROR,
+ "%p\n%a",
+ Options::program_name,
+ 1));
+
+ if (Options::get_opt (Options::DEBUG))
+ ACE_DEBUG ((LM_DEBUG,
+ "disposing the RWho_DB_Manager\n"));
+}
+
+// This procedure looks through the rwhod directory until it finds the next
+// valid user file.
+//
+// The requirements for user files are:
+// 1) The file is at least MIN_HOST_DATA_SIZE bytes long
+// 2) It was received within the last MAX_HOST_TIMEOUT seconds
+// Return:
+// Are there any more hosts? */
+
+int
+RWho_DB_Manager::get_next_host (void)
+{
+ time_t current_time;
+
+ ACE_OS::time (&current_time);
+
+ // Go through each file in the directory looking for valid entries.
+
+ for (dirent *dir_ptr = this->rwho_dir.read ();
+ dir_ptr != 0;
+ dir_ptr = this->rwho_dir.read ())
+ {
+ ACE_HANDLE user_file =
+ ACE_OS::open (dir_ptr->d_name, O_RDONLY);
+
+ if (user_file < 0)
+ return -1;
+
+ int host_data_length =
+ ACE_OS::read (user_file,
+ (char *) &this->host_data,
+ sizeof this->host_data);
+
+ if (host_data_length > WHOD_HEADER_SIZE
+ && current_time - this->host_data.wd_recvtime < MAX_HOST_TIMEOUT)
+ {
+ this->current_user = 0;
+ this->number_of_users = (host_data_length - WHOD_HEADER_SIZE) / sizeof *this->host_data.wd_we;
+ ACE_OS::close (user_file);
+ return 1; // We found a good host, so return it.
+ }
+ else
+ ACE_OS::close (user_file);
+ }
+
+ // There are no more hosts, so return False.
+ return 0;
+}
+
+// Returns the next user's information. Note that for efficiency only
+// pointers are copied, i.e., this info must be used before we call
+// this function again.
+
+int
+RWho_DB_Manager::get_next_user (Protocol_Record &protocol_record)
+{
+ // Get the next host file if necessary
+ if (this->current_user >= this->number_of_users
+ && this->get_next_host () == 0)
+ return 0;
+
+ protocol_record.set_login (this->host_data.wd_we[current_user].we_utmp.out_name);
+ Drwho_Node *current_node = protocol_record.get_drwho_list ();
+ current_node->set_host_name (this->host_data.wd_hostname);
+ current_node->set_idle_time (this->host_data.wd_we[current_user].we_idle);
+ this->current_user++;
+
+ return 1;
+}
diff --git a/ACE/apps/drwho/Rwho_DB_Manager.h b/ACE/apps/drwho/Rwho_DB_Manager.h
new file mode 100644
index 00000000000..2dd8bf73128
--- /dev/null
+++ b/ACE/apps/drwho/Rwho_DB_Manager.h
@@ -0,0 +1,53 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// Rwho_DB_Manager.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _RWHO_DB_MANAGER_H
+#define _RWHO_DB_MANAGER_H
+
+#include <sys/types.h>
+#include <protocols/rwhod.h>
+#include "ace/Dirent.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "Protocol_Record.h"
+
+class RWho_DB_Manager
+{
+ // = TITLE
+ // This class returns the user/machine pairs one at a time from
+ // the rwho database.
+
+public:
+ RWho_DB_Manager (void);
+ ~RWho_DB_Manager (void);
+ int get_next_user (Protocol_Record &protocol_record);
+
+private:
+ ACE_Dirent rwho_dir;
+ whod host_data;
+ int number_of_users;
+ int current_user;
+ const int WHOD_HEADER_SIZE;
+ char original_pathname[MAXPATHLEN + 1];
+ const char *rwho_dir_name;
+
+ int get_next_host (void);
+};
+
+#endif /* _RWHO_DB_MANAGER_H */
diff --git a/ACE/apps/drwho/SL_Client.cpp b/ACE/apps/drwho/SL_Client.cpp
new file mode 100644
index 00000000000..9cba5324a2e
--- /dev/null
+++ b/ACE/apps/drwho/SL_Client.cpp
@@ -0,0 +1,15 @@
+// $Id$
+
+#include "Options.h"
+#include "SL_Client.h"
+
+SL_Client::SL_Client (const char *usr_name)
+ : Single_Lookup (usr_name)
+{
+}
+
+Protocol_Record *
+SL_Client::insert (const char *, int)
+{
+ return this->prp_;
+}
diff --git a/ACE/apps/drwho/SL_Client.h b/ACE/apps/drwho/SL_Client.h
new file mode 100644
index 00000000000..16be3842064
--- /dev/null
+++ b/ACE/apps/drwho/SL_Client.h
@@ -0,0 +1,33 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// SL_Client.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _SL_CLIENT_H
+#define _SL_CLIENT_H
+
+#include "Single_Lookup.h"
+
+class SL_Client : public Single_Lookup
+{
+ // = TITLE
+ // Provides the client's single user lookup table abstraction.
+
+public:
+ SL_Client (const char *key_name);
+ virtual Protocol_Record *insert (const char *key_name,
+ int max_len = MAXUSERIDNAMELEN);
+};
+
+#endif /* _SL_CLIENT_H */
diff --git a/ACE/apps/drwho/SL_Server.cpp b/ACE/apps/drwho/SL_Server.cpp
new file mode 100644
index 00000000000..7dc172deb08
--- /dev/null
+++ b/ACE/apps/drwho/SL_Server.cpp
@@ -0,0 +1,26 @@
+// $Id$
+
+#include "global.h"
+#include "SL_Server.h"
+#include "ace/OS_NS_string.h"
+
+SL_Server::SL_Server (const char *usr_name)
+ : Single_Lookup (usr_name)
+{
+}
+
+Protocol_Record *
+SL_Server::get_each_entry (void)
+{
+ Protocol_Record *prp = Single_Lookup::get_each_entry ();
+ return prp->get_drwho_list () == 0 ? 0 : prp;
+}
+
+Protocol_Record *
+SL_Server::insert (const char *key_name, int max_len)
+{
+ return ACE_OS::strncmp (key_name,
+ this->prp_->get_login (),
+ max_len) == 0 ? this->prp_ : 0;
+}
+
diff --git a/ACE/apps/drwho/SL_Server.h b/ACE/apps/drwho/SL_Server.h
new file mode 100644
index 00000000000..2a8ee2ba054
--- /dev/null
+++ b/ACE/apps/drwho/SL_Server.h
@@ -0,0 +1,34 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// SL_Server.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _SL_SERVER_H
+#define _SL_SERVER_H
+
+#include "Single_Lookup.h"
+
+class SL_Server : public Single_Lookup
+{
+ // = TITLE
+ // Provides the server's single user lookup table abstraction.
+
+public:
+ SL_Server (const char *packet);
+ virtual Protocol_Record *insert (const char *key_name,
+ int max_len = MAXUSERIDNAMELEN);
+ virtual Protocol_Record *get_each_entry (void);
+};
+
+#endif /* _SL_SERVER_H */
diff --git a/ACE/apps/drwho/SML_Client.cpp b/ACE/apps/drwho/SML_Client.cpp
new file mode 100644
index 00000000000..8ae0195e1a6
--- /dev/null
+++ b/ACE/apps/drwho/SML_Client.cpp
@@ -0,0 +1,36 @@
+// $Id$
+
+#include "Options.h"
+#include "SML_Client.h"
+
+int
+SML_Client::receive (int)
+{
+ if (sml_server.mux (this->recv_packet_, this->packet_length) < 0)
+ return -1;
+
+ if (this->demux (this->recv_packet_, this->packet_length) < 0)
+ return -1;
+
+ return 1;
+}
+
+int
+SML_Client::send (void)
+{
+ if (this->mux (this->send_packet_, this->packet_length) < 0)
+ return -1;
+
+ if (sml_server.demux (this->send_packet_, this->packet_length) < 0)
+ return -1;
+
+ return 1;
+}
+
+SML_Client::SML_Client (void)
+{
+}
+
+SML_Client::~SML_Client (void)
+{
+}
diff --git a/ACE/apps/drwho/SML_Client.h b/ACE/apps/drwho/SML_Client.h
new file mode 100644
index 00000000000..d02fb8d6fa0
--- /dev/null
+++ b/ACE/apps/drwho/SML_Client.h
@@ -0,0 +1,36 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// SML_Client.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _SML_CLIENT_H
+#define _SML_CLIENT_H
+
+#include "SM_Client.h"
+#include "SML_Server.h"
+
+class SML_Client : public SM_Client
+{
+public:
+ SML_Client (void);
+ virtual ~SML_Client (void);
+ virtual int receive (int timeout = 0);
+ virtual int send (void);
+
+private:
+ SML_Server sml_server;
+ int packet_length;
+};
+
+#endif /* _SML_CLIENT_H */
diff --git a/ACE/apps/drwho/SML_Server.cpp b/ACE/apps/drwho/SML_Server.cpp
new file mode 100644
index 00000000000..5a71c795f69
--- /dev/null
+++ b/ACE/apps/drwho/SML_Server.cpp
@@ -0,0 +1,11 @@
+// $Id$
+
+#include "SML_Server.h"
+
+SML_Server::SML_Server (void)
+{
+}
+
+SML_Server::~SML_Server (void)
+{
+}
diff --git a/ACE/apps/drwho/SML_Server.h b/ACE/apps/drwho/SML_Server.h
new file mode 100644
index 00000000000..5fc665450df
--- /dev/null
+++ b/ACE/apps/drwho/SML_Server.h
@@ -0,0 +1,29 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// SML_Server.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _SML_SERVER_H
+#define _SML_SERVER_H
+
+#include "SM_Server.h"
+
+class SML_Server : public SM_Server
+{
+public:
+ SML_Server (void);
+ virtual ~SML_Server (void);
+};
+
+#endif /* _SML_SERVER_H */
diff --git a/ACE/apps/drwho/SMR_Client.cpp b/ACE/apps/drwho/SMR_Client.cpp
new file mode 100644
index 00000000000..c7dae2ca3f7
--- /dev/null
+++ b/ACE/apps/drwho/SMR_Client.cpp
@@ -0,0 +1,22 @@
+// $Id$
+
+#include "Options.h"
+#include "PMC_All.h"
+#include "PMC_Flo.h"
+#include "PMC_Usr.h"
+#include "PMC_Ruser.h"
+#include "SMR_Client.h"
+#include "ace/Log_Msg.h"
+
+SMR_Client::SMR_Client (short port_number)
+{
+ if (CM_Client::open (port_number) < 0)
+ ACE_ERROR ((LM_ERROR,
+ "%p\n%a",
+ Options::program_name,
+ 1));
+}
+
+SMR_Client::~SMR_Client (void)
+{
+}
diff --git a/ACE/apps/drwho/SMR_Client.h b/ACE/apps/drwho/SMR_Client.h
new file mode 100644
index 00000000000..9725c3ebd96
--- /dev/null
+++ b/ACE/apps/drwho/SMR_Client.h
@@ -0,0 +1,29 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// SMR_Client.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _SMR_CLIENT_H
+#define _SMR_CLIENT_H
+
+#include "SM_Client.h"
+
+class SMR_Client : public SM_Client
+{
+public:
+ SMR_Client (short port_number);
+ virtual ~SMR_Client (void);
+};
+
+#endif /* _SMR_CLIENT_H */
diff --git a/ACE/apps/drwho/SMR_Server.cpp b/ACE/apps/drwho/SMR_Server.cpp
new file mode 100644
index 00000000000..0801e0e1db1
--- /dev/null
+++ b/ACE/apps/drwho/SMR_Server.cpp
@@ -0,0 +1,18 @@
+// $Id$
+
+#include "Options.h"
+#include "SMR_Server.h"
+#include "ace/Log_Msg.h"
+
+SMR_Server::SMR_Server (short port_number)
+{
+ if (CM_Server::open (port_number) < 0)
+ ACE_ERROR ((LM_ERROR,
+ "%p\n%a",
+ Options::program_name,
+ 1));
+}
+
+SMR_Server::~SMR_Server (void)
+{
+}
diff --git a/ACE/apps/drwho/SMR_Server.h b/ACE/apps/drwho/SMR_Server.h
new file mode 100644
index 00000000000..af8b384d701
--- /dev/null
+++ b/ACE/apps/drwho/SMR_Server.h
@@ -0,0 +1,29 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// SMR_Server.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _SMR_SERVER_H
+#define _SMR_SERVER_H
+
+#include "SM_Server.h"
+
+class SMR_Server : public SM_Server
+{
+public:
+ SMR_Server (short port_number);
+ ~SMR_Server (void);
+};
+
+#endif /* _SMR_SERVER_H */
diff --git a/ACE/apps/drwho/SM_Client.cpp b/ACE/apps/drwho/SM_Client.cpp
new file mode 100644
index 00000000000..02e552c9af9
--- /dev/null
+++ b/ACE/apps/drwho/SM_Client.cpp
@@ -0,0 +1,75 @@
+// $Id$
+
+#include "Options.h"
+#include "PMC_All.h"
+#include "PMC_Flo.h"
+#include "PMC_Usr.h"
+#include "PMC_Ruser.h"
+#include "SM_Client.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_Memory.h"
+
+// Call-back function that invokes the appropriate decode function.
+
+int
+SM_Client::demux (char *packet,
+ int &packet_length)
+{
+ if (this->pm_client->decode (packet, packet_length) < 0)
+ return -1;
+ else
+ return 1;
+}
+
+// Call-back function that invokes the appropriate encode function.
+
+int
+SM_Client::mux (char *packet, int &packet_length)
+{
+ switch (Options::protocol_type)
+ {
+ case Options::PROTO_USR:
+ ACE_NEW_RETURN (this->pm_client,
+ PMC_Usr (Options::user_name),
+ -1);
+ break;
+ case Options::PROTO_ALL:
+ ACE_NEW_RETURN (this->pm_client,
+ PMC_All,
+ -1);
+ break;
+ case Options::PROTO_FLO:
+ ACE_NEW_RETURN (this->pm_client,
+ PMC_Flo,
+ -1);
+ break;
+ case Options::PROTO_RUSER:
+ ACE_NEW_RETURN (this->pm_client,
+ PMC_Ruser,
+ -1);
+ break;
+ default:
+ ACE_DEBUG ((LM_DEBUG,
+ "%s: bad protocol\n",
+ Options::program_name));
+ return -1;
+ }
+
+ if (this->pm_client->encode (packet, packet_length) < 0)
+ return -1;
+ return 1;
+}
+
+SM_Client::SM_Client (void)
+{
+}
+
+SM_Client::~SM_Client (void)
+{
+}
+
+void
+SM_Client::process (void)
+{
+ this->pm_client->process ();
+}
diff --git a/ACE/apps/drwho/SM_Client.h b/ACE/apps/drwho/SM_Client.h
new file mode 100644
index 00000000000..0a262f71c78
--- /dev/null
+++ b/ACE/apps/drwho/SM_Client.h
@@ -0,0 +1,38 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// SM_Client.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _SM_CLIENT_H
+#define _SM_CLIENT_H
+
+#include "PM_Client.h"
+#include "CM_Client.h"
+#include "Select_Manager.h"
+
+class SM_Client : public Select_Manager, public CM_Client
+{
+public:
+ SM_Client (void);
+ virtual ~SM_Client (void);
+
+ virtual int mux (char *packet, int &packet_length);
+ virtual int demux (char *packet, int &packet_length);
+ virtual void process (void);
+
+private:
+ PM_Client *pm_client;
+};
+
+#endif /* _SM_CLIENT_H */
diff --git a/ACE/apps/drwho/SM_Server.cpp b/ACE/apps/drwho/SM_Server.cpp
new file mode 100644
index 00000000000..25a43375524
--- /dev/null
+++ b/ACE/apps/drwho/SM_Server.cpp
@@ -0,0 +1,69 @@
+// $Id$
+
+#include "Options.h"
+#include "PMS_All.h"
+#include "PMS_Flo.h"
+#include "PMS_Usr.h"
+#include "PMS_Ruser.h"
+#include "SM_Server.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_Memory.h"
+
+int
+SM_Server::demux (char *packet, int &packet_length)
+{
+ switch (GET_PACKET_TYPE (packet))
+ {
+ case Options::PROTO_USR:
+ ACE_NEW_RETURN (this->pm_server,
+ PMS_Usr,
+ -1);
+ break;
+ case Options::PROTO_ALL:
+ ACE_NEW_RETURN (this->pm_server,
+ PMS_All,
+ -1);
+ break;
+ case Options::PROTO_FLO:
+ ACE_NEW_RETURN (this->pm_server,
+ PMS_Flo,
+ -1);
+ break;
+ case Options::PROTO_RUSER:
+ ACE_NEW_RETURN (this->pm_server,
+ PMS_Ruser,
+ -1);
+ break;
+ default:
+ ACE_DEBUG ((LM_DEBUG,
+ "%s: bad protocol\n",
+ Options::program_name));
+ return -1;
+ }
+
+ packet_length = SUBTRACT_PACKET_TYPE (packet_length);
+
+ if (pm_server->decode (SKIP_PACKET_TYPE (packet),
+ packet_length) < 0)
+ return -1;
+
+ if (pm_server->process () < 0)
+ return -1;
+
+ return 1;
+}
+
+int
+SM_Server::mux (char *packet,
+ int &packet_length)
+{
+ return pm_server->encode (packet, packet_length);
+}
+
+SM_Server::SM_Server (void)
+{
+}
+
+SM_Server::~SM_Server (void)
+{
+}
diff --git a/ACE/apps/drwho/SM_Server.h b/ACE/apps/drwho/SM_Server.h
new file mode 100644
index 00000000000..f9fbc9857d1
--- /dev/null
+++ b/ACE/apps/drwho/SM_Server.h
@@ -0,0 +1,36 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// SM_Server.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _SM_SERVER_H
+#define _SM_SERVER_H
+
+#include "PM_Server.h"
+#include "CM_Server.h"
+#include "Select_Manager.h"
+
+class SM_Server : public Select_Manager, public CM_Server
+{
+public:
+ SM_Server (void);
+ virtual ~SM_Server (void);
+ virtual int mux (char *packet, int &packet_length);
+ virtual int demux (char *packet, int &packet_length);
+
+private:
+ PM_Server *pm_server;
+};
+
+#endif /* _SM_SERVER_H */
diff --git a/ACE/apps/drwho/Search_Struct.cpp b/ACE/apps/drwho/Search_Struct.cpp
new file mode 100644
index 00000000000..a7c99de589b
--- /dev/null
+++ b/ACE/apps/drwho/Search_Struct.cpp
@@ -0,0 +1,23 @@
+// $Id$
+
+#include "Options.h"
+#include "Search_Struct.h"
+#include "ace/Log_Msg.h"
+
+Search_Struct::~Search_Struct (void)
+{
+ if (Options::get_opt (Options::DEBUG))
+ ACE_DEBUG ((LM_DEBUG,
+ "disposing Search_Struct\n"));
+}
+
+Search_Struct::Search_Struct (void)
+ : count_ (0)
+{}
+
+int
+Search_Struct::n_elems (void)
+{
+ return this->count_;
+}
+
diff --git a/ACE/apps/drwho/Search_Struct.h b/ACE/apps/drwho/Search_Struct.h
new file mode 100644
index 00000000000..c45dcbf6086
--- /dev/null
+++ b/ACE/apps/drwho/Search_Struct.h
@@ -0,0 +1,41 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// Search_Struct.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _SEARCH_STRUCT_H
+#define _SEARCH_STRUCT_H
+
+#include "Protocol_Record.h"
+
+class Search_Struct
+{
+ // = TITLE
+ // Provides an "Abstract Base Class" lookup table abstraction that
+ // stores and manipulates friend records.
+public:
+ Search_Struct (void);
+ virtual ~Search_Struct (void);
+ virtual int n_elems (void);
+
+ virtual Protocol_Record *insert (const char *key_name,
+ int max_len = MAXUSERIDNAMELEN) = 0;
+ virtual Protocol_Record *get_next_entry (void) = 0;
+ virtual Protocol_Record *get_each_entry (void) = 0;
+
+protected:
+ int count_;
+};
+
+#endif /* _SEARCH_STRUCT_H */
diff --git a/ACE/apps/drwho/Select_Manager.cpp b/ACE/apps/drwho/Select_Manager.cpp
new file mode 100644
index 00000000000..0570649500e
--- /dev/null
+++ b/ACE/apps/drwho/Select_Manager.cpp
@@ -0,0 +1,8 @@
+// $Id$
+
+#include "Select_Manager.h"
+
+
+Select_Manager::~Select_Manager (void)
+{
+}
diff --git a/ACE/apps/drwho/Select_Manager.h b/ACE/apps/drwho/Select_Manager.h
new file mode 100644
index 00000000000..9fed1bc1195
--- /dev/null
+++ b/ACE/apps/drwho/Select_Manager.h
@@ -0,0 +1,32 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// Select_Manager.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _SELECT_MANAGER_H
+#define _SELECT_MANAGER_H
+
+class Select_Manager
+{
+public:
+ virtual ~Select_Manager (void);
+
+ virtual int mux (char *packet,
+ int &packet_length) = 0 ;
+
+ virtual int demux (char *packet,
+ int &packet_length) = 0;
+};
+
+#endif /* _SELECT_MANAGER_H */
diff --git a/ACE/apps/drwho/Single_Lookup.cpp b/ACE/apps/drwho/Single_Lookup.cpp
new file mode 100644
index 00000000000..d435e19fc6e
--- /dev/null
+++ b/ACE/apps/drwho/Single_Lookup.cpp
@@ -0,0 +1,32 @@
+// $Id$
+
+#include "Options.h"
+#include "Single_Lookup.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_Memory.h"
+
+Single_Lookup::Single_Lookup (const char *usr_name)
+{
+ ACE_NEW (this->prp_,
+ Protocol_Record (ACE::strnew (usr_name)));
+}
+
+Single_Lookup::~Single_Lookup (void)
+{
+ if (Options::get_opt (Options::DEBUG))
+ ACE_DEBUG ((LM_DEBUG,
+ "disposing Single_Lookup\n"));
+}
+
+Protocol_Record *
+Single_Lookup::get_each_entry (void)
+{
+ return this->prp_;
+}
+
+Protocol_Record *
+Single_Lookup::get_next_entry (void)
+{
+ return this->get_each_entry ();
+}
diff --git a/ACE/apps/drwho/Single_Lookup.h b/ACE/apps/drwho/Single_Lookup.h
new file mode 100644
index 00000000000..fa86301215e
--- /dev/null
+++ b/ACE/apps/drwho/Single_Lookup.h
@@ -0,0 +1,39 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// Single_Lookup.h
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _SINGLE_LOOKUP_H
+#define _SINGLE_LOOKUP_H
+
+#include "Options.h"
+#include "Search_Struct.h"
+
+class Single_Lookup : public Search_Struct
+{
+ // = DESCRIPTION
+ // Provides the client's single user lookup table abstraction.
+public:
+ Single_Lookup (const char *usr_name);
+ virtual ~Single_Lookup (void);
+ virtual Protocol_Record *insert (const char *key_name,
+ int max_len = MAXUSERIDNAMELEN) = 0;
+ virtual Protocol_Record *get_next_entry (void);
+ virtual Protocol_Record *get_each_entry (void);
+
+protected:
+ Protocol_Record *prp_;
+};
+
+#endif /* _SINGLE_LOOKUP_H */
diff --git a/ACE/apps/drwho/client.cpp b/ACE/apps/drwho/client.cpp
new file mode 100644
index 00000000000..5b8f4fcf8ab
--- /dev/null
+++ b/ACE/apps/drwho/client.cpp
@@ -0,0 +1,66 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// client.cpp
+//
+// = DESCRIPTION
+// Client driver program for drwho.
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#include "ace/Log_Msg.h"
+
+#include "Options.h"
+#include "SML_Client.h"
+#include "SMR_Client.h"
+#include "ace/OS_Memory.h"
+
+// Factory function.
+
+static SM_Client *
+make_client (void)
+{
+ SM_Client *client = 0;
+
+ if (Options::get_opt (Options::REMOTE_USAGE) == 0)
+ ACE_NEW_RETURN (client,
+ SML_Client,
+ 0);
+ else
+ ACE_NEW_RETURN (client,
+ SMR_Client (Options::port_number),
+ 0);
+ return client;
+}
+
+int
+main (int argc, char *argv[])
+{
+ Options::set_options (argc, argv);
+
+ SM_Client *sm_client = make_client ();
+
+ if (sm_client->send () < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "%p\n",
+ Options::program_name),
+ -1);
+
+ if (sm_client->receive (Options::max_server_timeout) < 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "%p\n",
+ Options::program_name),
+ -1);
+
+ sm_client->process ();
+
+ return 0;
+}
diff --git a/ACE/apps/drwho/drwho.mpc b/ACE/apps/drwho/drwho.mpc
new file mode 100644
index 00000000000..ca623976a94
--- /dev/null
+++ b/ACE/apps/drwho/drwho.mpc
@@ -0,0 +1,94 @@
+// -*- MPC -*-
+// $Id$
+
+project(*-client) : aceexe {
+ requires += rwho
+ avoids += uses_wchar ace_for_tao
+ Source_Files {
+ Comm_Manager.cpp
+ Select_Manager.cpp
+ Protocol_Manager.cpp
+ Drwho_Node.cpp
+ Rwho_DB_Manager.cpp
+ Multicast_Manager.cpp
+ Protocol_Record.cpp
+ Options.cpp
+ File_Manager.cpp
+ Hash_Table.cpp
+ Binary_Search.cpp
+ Search_Struct.cpp
+ Single_Lookup.cpp
+ SML_Server.cpp
+ SM_Server.cpp
+ PMS_Usr.cpp
+ SL_Server.cpp
+ PMS_Flo.cpp
+ PM_Server.cpp
+ HT_Server.cpp
+ BS_Server.cpp
+ PMS_All.cpp
+ PMS_Ruser.cpp
+ SMR_Server.cpp
+ CM_Client.cpp
+ SM_Client.cpp
+ SMR_Client.cpp
+ PM_Client.cpp
+ HT_Client.cpp
+ BS_Client.cpp
+ PMC_All.cpp
+ PMC_Flo.cpp
+ PMC_Usr.cpp
+ SL_Client.cpp
+ PMC_Ruser.cpp
+ SMR_Client.cpp
+ SML_Client.cpp
+ CM_Server.cpp
+ client.cpp
+ }
+}
+
+project(*-server) : aceexe {
+ requires += rwho
+ avoids += uses_wchar ace_for_tao
+ Source_Files {
+ Comm_Manager.cpp
+ Select_Manager.cpp
+ Protocol_Manager.cpp
+ Drwho_Node.cpp
+ Rwho_DB_Manager.cpp
+ Multicast_Manager.cpp
+ Protocol_Record.cpp
+ Options.cpp
+ File_Manager.cpp
+ Hash_Table.cpp
+ Binary_Search.cpp
+ Search_Struct.cpp
+ Single_Lookup.cpp
+ SML_Server.cpp
+ SM_Server.cpp
+ PMS_Usr.cpp
+ SL_Server.cpp
+ PMS_Flo.cpp
+ PM_Server.cpp
+ HT_Server.cpp
+ BS_Server.cpp
+ PMS_All.cpp
+ PMS_Ruser.cpp
+ SMR_Server.cpp
+ CM_Client.cpp
+ SM_Client.cpp
+ SMR_Client.cpp
+ PM_Client.cpp
+ HT_Client.cpp
+ BS_Client.cpp
+ PMC_All.cpp
+ PMC_Flo.cpp
+ PMC_Usr.cpp
+ SL_Client.cpp
+ PMC_Ruser.cpp
+ SMR_Client.cpp
+ SML_Client.cpp
+ CM_Server.cpp
+ server.cpp
+ }
+}
diff --git a/ACE/apps/drwho/global.h b/ACE/apps/drwho/global.h
new file mode 100644
index 00000000000..c6713f0063e
--- /dev/null
+++ b/ACE/apps/drwho/global.h
@@ -0,0 +1,52 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// global.h
+//
+// = DESCRIPTION
+// Here are all the declarations that are needed throughout the program. */
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#ifndef _GLOBAL_H
+#define _GLOBAL_H
+
+#include "ace/config-all.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+// These constants are used throughout drwho.
+
+enum
+{
+ MAXUSERIDNAMELEN = 8,
+ MAX_USER_TIMEOUT = 300,
+ MAX_HOST_TIMEOUT = 300,
+ UDP_PACKET_SIZE = 1024 * 8,
+ PORT_NUMBER = 12344
+};
+
+// Default name of file where friends info is stored.
+#define FRIEND_FILE ".friends.dta"
+
+// Default name where rwho info is stored.
+#define RWHODIR "/usr/spool/rwho"
+
+// Macros for handling message types.
+#define GET_PACKET_TYPE(P) (ntohs (*((short *) P)))
+#define SET_PACKET_TYPE(P,T) ((*(short *) P) = ntohs (T))
+#define SKIP_PACKET_TYPE(P) ((P) + sizeof (short))
+#define SUBTRACT_PACKET_TYPE(L) ((L) - sizeof (short))
+
+#endif /* _GLOBAL_H */
diff --git a/ACE/apps/drwho/server.cpp b/ACE/apps/drwho/server.cpp
new file mode 100644
index 00000000000..aa4bea1349b
--- /dev/null
+++ b/ACE/apps/drwho/server.cpp
@@ -0,0 +1,117 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// drwho
+//
+// = FILENAME
+// server.cpp
+//
+// = DESCRIPTION
+// Driver program for the server. Note that it is easy to reuse the
+// server for other distributed programs. Pretty much all that must
+// change are the functions registered with the communciations
+// manager.
+//
+// = AUTHOR
+// Douglas C. Schmidt
+//
+// ============================================================================
+
+#include "Options.h"
+#include "SMR_Server.h"
+#include "ace/ACE.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_signal.h"
+#include "ace/OS_NS_time.h"
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_sys_socket.h"
+
+static char *
+time_stamp (void)
+{
+ time_t time_now;
+ char *temp;
+
+ time_now = ACE_OS::time (0);
+ temp = ACE_OS::asctime (ACE_OS::localtime (&time_now));
+ temp[12] = 0;
+ return temp;
+}
+
+// Catch the obvious signals and die with dignity...
+
+static void
+exit_server (int sig)
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "%s exiting on signal %S\n",
+ time_stamp (),
+ sig));
+ ACE_OS::exit (0);
+}
+
+// Returns TRUE if the program was started by INETD.
+
+static int
+started_by_inetd (void)
+{
+ sockaddr_in sin;
+ int size = sizeof sin;
+
+ return ACE_OS::getsockname (0,
+ reinterpret_cast<sockaddr *> (&sin),
+ &size) == 0;
+}
+
+// Does the drwho service.
+
+static void
+do_drwho (SMR_Server &smr_server)
+{
+ if (smr_server.receive () == -1)
+ ACE_ERROR ((LM_ERROR,
+ "%p\n",
+ Options::program_name));
+
+ if (smr_server.send () == -1)
+ ACE_ERROR ((LM_ERROR,
+ "%p\n",
+ Options::program_name));
+}
+
+// If the server is started with any argument at all then it doesn't
+// fork off a child process to do the work. This is useful when
+// debugging!
+
+int
+main (int argc, char *argv[])
+{
+ ACE_OS::signal (SIGTERM, (ACE_SignalHandler)exit_server);
+ ACE_OS::signal (SIGINT, (ACE_SignalHandler)exit_server);
+ ACE_OS::signal (SIGQUIT, (ACE_SignalHandler)exit_server);
+
+ Options::set_options (argc, argv);
+ Options::set_opt (Options::STAND_ALONE_SERVER);
+
+ int inetd_controlled = started_by_inetd ();
+
+ if (!inetd_controlled && Options::get_opt (Options::BE_A_DAEMON))
+ ACE::daemonize ();
+
+ SMR_Server smr_server (Options::port_number);
+
+ if (inetd_controlled)
+ do_drwho (smr_server);
+ else
+ {
+
+ for (;;)
+ do_drwho (smr_server);
+
+ /* NOTREACHED */
+ }
+
+ return 0;
+}