summaryrefslogtreecommitdiff
path: root/comm/Address.cc
diff options
context:
space:
mode:
authorchatty1993-04-07 11:50:31 +0000
committerchatty1993-04-07 11:50:31 +0000
commitba066c34dde204aa192d03a23a81356374d93731 (patch)
tree39391f6235d2cf8a59a0634ac5ea430cdd21f5d4 /comm/Address.cc
parent05ab076e1c2a9ca16472f9a6b47b8d22914b3783 (diff)
downloadivy-league-ba066c34dde204aa192d03a23a81356374d93731.zip
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.gz
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.bz2
ivy-league-ba066c34dde204aa192d03a23a81356374d93731.tar.xz
Initial revision
Diffstat (limited to 'comm/Address.cc')
-rw-r--r--comm/Address.cc350
1 files changed, 350 insertions, 0 deletions
diff --git a/comm/Address.cc b/comm/Address.cc
new file mode 100644
index 0000000..789a370
--- /dev/null
+++ b/comm/Address.cc
@@ -0,0 +1,350 @@
+/*
+ * The Unix Channel
+ *
+ * by Michel Beaudouin-Lafon
+ *
+ * Copyright 1990-1993
+ * Laboratoire de Recherche en Informatique (LRI)
+ *
+ * Addresses
+ *
+ * $Id$
+ * $CurLog$
+ */
+
+#include "Address.h"
+#include "error.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <memory.h>
+#include <netdb.h>
+
+/*?class UchAddress
+This class is a virtual base class: no objects of this class are ever created.
+It implements the Unix type \typ{^{struct sockaddr}}, used for creating sockets.
+Addresses are used mainly as arguments of constructors for the class
+\typ{UchSocket} and its derived classes.
+All its member functions are virtual.
+These functions exist for all the derived classes but are only described here.
+An address can be valid or invalid, depending on the constructor being able to create the address or not.
+There are currently two derived classes, for Unix domain addresses and Internet domain addresses.
+
+The class \typ{^{pUchAddress}} implements smart pointers to addresses.
+Smart pointers behave like pointers but they manage a reference count on the
+pointed to objects for an automatic reclaim of dynamically allocated objects.
+?*/
+
+/*?
+Construct an invalid address.
+?*/
+UchAddress :: UchAddress ()
+: Valid (FALSE)
+{
+}
+
+/*?nodoc?*/
+UchAddress :: ~UchAddress ()
+{
+}
+
+// virtual functions for class address
+//
+
+/*?
+Return one of \var{AF_UNSPEC}, \var{AF_UNIX} or \var{AF_INET}.
+Other values may be defined if supported by the system.
+?*/
+int
+UchAddress :: Family ()
+{
+ return AF_UNSPEC;
+}
+
+/*?nextdoc?*/
+int
+UchAddress :: Length ()
+{
+ return 0;
+}
+
+/*?
+Return the address structure and its length.
+\typ{^{SockAddr}} is a typedef for \typ{^{struct sockaddr}}.
+?*/
+SockAddr*
+UchAddress :: GetSockAddr ()
+{
+ return 0;
+}
+
+/*?nodoc?*/
+char*
+UchAddress :: StrRepr (char* buf)
+{
+ strcpy (buf, "virtual address !");
+ return buf;
+}
+
+#ifdef UNIX_SOCK
+
+// constructors for Unix addresses
+// a Unix domain address is just a filename
+// -> some problems: check for access, when to unlink it ?
+// to do : generate name from a template (for uniqueness)
+//
+
+/*?nodoc?*/
+UchUnixAddress :: UchUnixAddress ()
+: UchAddress ()
+{
+ // nothing
+}
+
+/*?
+Create a Unix domain address associated to file \var{filename}.
+The file is not unlinked when the address is destroyed;
+it should be unlinked by the application whenever the last socket using this address is closed.
+?*/
+UchUnixAddress :: UchUnixAddress (const char* filename)
+: UchAddress ()
+{
+ Addr.sun_family = AF_UNIX;
+ strcpy (Addr.sun_path, filename);
+ Valid = TRUE; // should check access to file ???
+ // unlink if already there ?
+}
+
+/*?nodoc?*/
+UchUnixAddress :: ~UchUnixAddress ()
+{
+ // how to unlink the file ??
+}
+
+/*?nodoc?*/
+int
+UchUnixAddress :: Family ()
+{
+ return AF_UNIX;
+}
+
+/*?nodoc?*/
+int
+UchUnixAddress :: Length ()
+{
+ if (Valid)
+ return (Addr.sun_path + strlen (Addr.sun_path)) - (char*) &Addr;
+ return 0;
+}
+
+/*?nodoc?*/
+SockAddr*
+UchUnixAddress :: GetSockAddr ()
+{
+ return (SockAddr*) &Addr;
+}
+
+/*?nodoc?*/
+char*
+UchUnixAddress :: StrRepr (char* buf)
+{
+ sprintf (buf, "%s", Addr.sun_path);
+ return buf;
+}
+
+#endif /* UNIX_SOCK */
+
+// constructors for inet addresses
+// inet address specified by:
+// hostname / port# (ANY if hostname is NIL, LOOPBACK if hostname is "")
+// hostid / port# (predefined hostids ANYADDR, ...)
+// todo:
+// hostname / service name ??
+//
+/*?nodoc?*/
+UchInetAddress :: UchInetAddress ()
+: UchAddress ()
+{
+ // nothing
+}
+
+/*?
+Construct an inet address, from a hostname and a port number.
+The address is valid only if the host is valid.
+If \var{host} is the empty string, the loopback host is used;
+if it is the nil pointer, the wildcard is used.
+If the port number is 0, it will be allocated by the system.
+?*/
+UchInetAddress :: UchInetAddress (const char* name, sword port)
+: UchAddress ()
+{
+ struct hostent *host;
+
+ if (name && *name) {
+ host = gethostbyname (name);
+ if (! host)
+ return;
+ memcpy (&Addr.sin_addr, host->h_addr, host->h_length);
+ } else
+ Addr.sin_addr.s_addr = name ? INADDR_LOOPBACK : INADDR_ANY;
+ Addr.sin_family = AF_INET;
+ Addr.sin_port = htons (port);
+ Valid = TRUE;
+}
+
+/*?
+Construct an inet address, from a host id (internet address) and a port number.
+If the port number is 0, it is assigned by the system.
+The host ids \var{^{ANYADDR}}, \var{^{LOOPBACK}} and \var{^{BROADCAST}} are predefined.
+\var{ANYADDR} is used to receive messages from anywhere.
+\var{LOOPBACK} is the local host address.
+\var{BROADCAST} makes it possible to send data to all the hosts of a local area network.
+?*/
+UchInetAddress :: UchInetAddress (lword host, sword port)
+: UchAddress ()
+{
+ Addr.sin_family = AF_INET;
+ Addr.sin_port = htons (port);
+ Addr.sin_addr.s_addr = host;
+ Valid = TRUE;
+}
+
+/*?nodoc?*/
+UchInetAddress :: ~UchInetAddress ()
+{
+}
+
+/*?nodoc?*/
+int
+UchInetAddress :: Family ()
+{
+ return AF_INET;
+}
+
+/*?nodoc?*/
+int
+UchInetAddress :: Length ()
+{
+ return sizeof (Addr);
+}
+
+/*?nodoc?*/
+SockAddr*
+UchInetAddress :: GetSockAddr ()
+{
+ return (SockAddr*) &Addr;
+}
+
+/*?nodoc?*/
+char*
+UchInetAddress :: StrRepr (char* buf)
+{
+ struct hostent *host;
+ char *hname;
+ unsigned long saddr;
+
+ saddr = Addr.sin_addr.s_addr;
+ host = gethostbyaddr ((char*) &saddr, sizeof (long), AF_INET);
+ if (host)
+ hname = host->h_name;
+ else
+ if (saddr == INADDR_ANY)
+ hname = "ANY";
+ else if (saddr == INADDR_LOOPBACK)
+ hname = "LOOPBACK";
+ else if (saddr == INADDR_BROADCAST)
+ hname = "BROADCAST";
+ else
+ hname = "???";
+ sprintf (buf, "%s::%d", hname, ntohs (Addr.sin_port));
+ return buf;
+}
+
+/*?
+This is a global function (static member of class \typ{UchAddress}).
+It creates an object of a derived class of \typ{UchAddress} from a generic address
+(thus is cannot be replaced by a constructor).
+A generic address is the following union of address structures
+(it is typically returned by system calls like \fun{recvfrom}):
+\begin{ccode}
+typedef union {
+ struct sockaddr sa; // default
+ struct sockaddr_un su; // Unix
+ struct sockaddr_in si; // inet
+} GEN_ADDR;
+\end{ccode}
+?*/
+UchAddress*
+UchAddress :: Decode (GEN_ADDR* addr, int alen)
+{
+ switch (addr->sa.sa_family) {
+#ifdef UNIX_SOCK
+ case AF_UNIX :
+ addr->su.sun_path [alen] = 0;
+ return new UchUnixAddress (addr->su.sun_path);
+#endif
+ case AF_INET :
+ return new UchInetAddress (addr->si.sin_addr.s_addr, addr->si.sin_port);
+
+ default :
+ return 0;
+ }
+}
+
+/*?
+This is a global function (static member of class \typ{UchInetAddress}.
+It returns the internet address of the local host.
+This is different from the predefined address \var{LOOPBACK}:
+\var{LOOPBACK} is the same constant on each machine, so that it cannot
+be communicated across the network.
+The value returned by \fun{LoopBack} is the unique internet address of the local host.
+Thus it can be communicated to another host across the network.
+?*/
+lword
+UchInetAddress :: LoopBack ()
+{
+ static lword loopback = 0;
+
+ if (loopback)
+ return loopback;
+
+ struct hostent *host;
+ char name [128];
+
+ gethostname (name, sizeof (name));
+ host = gethostbyname (name);
+ if (! host) {
+ Error (ErrFatal, "address", "cannot get address of local host");
+ return 0;
+ }
+ return loopback = * ((lword *) host->h_addr);
+}
+
+#ifdef DOC
+// fake entries for inline functions
+
+/*?
+Return TRUE if the address is valid.
+?*/
+bool
+UchAddress :: IsValid ()
+{}
+
+/*?
+Return the host number of the address.
+?*/
+lword
+UchInetAddress :: Host ()
+{}
+
+/*?
+Return the port number of the address.
+?*/
+sword
+UchInetAddress :: Port ()
+{}
+
+#endif /* DOC */
+