File: [Development] / fam / fam / ServerHostRef.c++ (download)
Revision 1.1.1.1 (vendor branch), Thu Apr 24 19:08:26 2003 UTC (14 years, 5 months ago) by trev
Branch: sgi-fam, MAIN
CVS Tags: fam-2-6-10, HEAD Changes since 1.1: +0 -0
lines
Initial FAM CVS repository build..
-- Trev
|
// Copyright (C) 1999 Silicon Graphics, Inc. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of version 2 of the GNU General Public License as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it would be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, any
// license provided herein, whether implied or otherwise, is limited to
// this program in accordance with the express provisions of the GNU
// General Public License. Patent licenses, if any, provided herein do not
// apply to combinations of this program with other product or programs, or
// any other product whatsoever. This program is distributed without any
// warranty that the program is delivered free of the rightful claim of any
// third person by way of infringement or the like. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write the Free Software Foundation, Inc., 59
// Temple Place - Suite 330, Boston MA 02111-1307, USA.
#include "ServerHostRef.h"
#include <assert.h>
#include <netdb.h>
unsigned int ServerHostRef::count;
StringTable<ServerHost *> *ServerHostRef::hosts_by_name;
///////////////////////////////////////////////////////////////////////////////
// ServerHostRef methods simply maintain refcounts on ServerHosts.
ServerHostRef&
ServerHostRef::operator = (const ServerHostRef& that)
{
if (this != &that)
{
if (p && !--p->refcount)
delete p;
p = that.p;
if (p)
p->refcount++;
}
return *this;
}
ServerHostRef::~ServerHostRef()
{
if (!--p->refcount)
{
// Remove from hosts_by_name.
const char *name;
for (unsigned i = 0; ((name = hosts_by_name->key(i)) != NULL); )
if (hosts_by_name->value(i) == p)
hosts_by_name->remove(name);
else
i++;
delete p;
}
// When the last reference is gone, delete hosts_by_name.
if (!--count && hosts_by_name)
{ assert(!hosts_by_name->size());
delete hosts_by_name;
hosts_by_name = NULL;
}
}
ServerHost *
ServerHostRef::find(const char *name)
{
// Create hosts_by_name first time.
if (!hosts_by_name)
hosts_by_name = new StringTable<ServerHost *>;
// Look in list of existing hosts.
ServerHost *host = hosts_by_name->find(name);
if (host)
return host;
// Look up hostname via gethostbyname().
hostent *hp = gethostbyname(name);
char *fake_haliases[1];
in_addr fake_haddr;
in_addr *fake_haddrlist[2];
hostent fake_hostent;
if (!hp)
{
// gethostbyname() failed for some reason (e.g., ypbind
// is down or NIS map just changed, ethernet came unplugged,
// or something equally tragic).
//
// Fake it by building a hostent with an illegal address.
fake_haliases[0] = NULL;
fake_haddr.s_addr = 0;
fake_haddrlist[0] = &fake_haddr;
fake_haddrlist[1] = NULL;
fake_hostent.h_name = (char *) name;
fake_hostent.h_aliases = fake_haliases;
fake_hostent.h_addrtype = 0;
fake_hostent.h_length = sizeof fake_haddr;
fake_hostent.h_addr_list = (char **) fake_haddrlist;
hp = &fake_hostent;
}
assert(hp->h_length == sizeof (struct in_addr));
// Create new host.
host = new ServerHost(*hp);
// Add this host to hosts_by_name.
hosts_by_name->insert(name, host);
hosts_by_name->insert(hp->h_name, host);
for (char *const*p = hp->h_aliases; *p; p++)
hosts_by_name->insert(*p, host);
return host;
}