diff options
Diffstat (limited to 'server/hostm.c')
-rw-r--r-- | server/hostm.c | 1045 |
1 files changed, 0 insertions, 1045 deletions
diff --git a/server/hostm.c b/server/hostm.c deleted file mode 100644 index 4a029ea..0000000 --- a/server/hostm.c +++ /dev/null @@ -1,1045 +0,0 @@ -/* This file is part of the Project Athena Zephyr Notification System. - * It contains functions for communicating with the HostManager. - * - * Created by: John T. Kohl - * - * $Source$ - * $Author$ - * - * Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology. - * For copying and distribution information, see the file - * "mit-copyright.h". - */ - -#include <zephyr/mit-copyright.h> - -#ifndef lint -#ifndef SABER -static char rcsid_hostm_c[] = "$Id$"; -#endif -#endif - -#include "zserver.h" -#include <sys/socket.h> /* for AF_INET */ - -/* - * - * External functions: - * - * void hostm_dispatch(notice, auth, who, server) - * ZNotice_t *notice; - * int auth; - * struct sockaddr_in *who; - * ZServerDesc_t *server; - * - * void hostm_flush(host, server) - * ZHostList_t *host; - * ZServerDesc_t *server; - * - * void hostm_transfer(host, server) - * ZHostList_t *host; - * ZServerDesc_t *server; - * - * ZHostList_t *hostm_find_host(addr) - * struct in_addr *addr; - * - * ZServerDesc_t *hostm_find_server(addr) - * struct in_addr *addr; - * - * void hostm_shutdown() - * - * void hostm_losing(client, host) - * ZClient_t *client; - * ZHostList_t *host; - * - * void hostm_deathgram(sin, server) - * struct sockaddr_in *sin; - * ZServerDesc_t *server; - * - * void hostm_dump_hosts(fp) - * FILE *fp; - */ - -/* - * This module maintains two important structures. - * all_hosts is an array of all currently known hosts, and which server - * is responsible for that host. This list is kept sorted by IP address - * so that lookups can be fast (binary search). num_hosts contains the - * number of hosts to be found in the array. - * - * The losing hosts list is a linked list of all the clients (and their hosts) - * whose existence is in doubt. Any host on this list has already been sent - * a ping and is expected to reply immediately. - * As usual, the first element of the list is a placeholder header so we - * know when the list has been completely scanned. - */ - -struct hostlist { - ZHostList_t *host; /* ptr to host struct */ - int server_index; /* index of server in the table */ -}; - -typedef struct _losinghost { - struct _losinghost *q_forw; - struct _losinghost *q_back; - struct _ZHostList_t *lh_host; - timer lh_timer; - struct _ZClient_t *lh_client; -} losinghost; - -#define NULLHLT ((struct hostlist *) 0) - -static struct hostlist *all_hosts; - -static int num_hosts = 0; /* number of hosts in all_hosts */ -static long lose_timo = LOSE_TIMO; - -static losinghost *losing_hosts; /* queue of pings for hosts we - doubt are really there */ - -#ifdef __STDC__ -# define P(s) s -#else -# define P(s) () -#endif - -static void host_detach P((register ZHostList_t *host, ZServerDesc_t *server)), - insert_host P((ZHostList_t *host, ZServerDesc_t *server)), - remove_host P((ZHostList_t *host)); -static void host_not_losing P((struct sockaddr_in *who)), - host_lost P((void *which)), - ping P((struct sockaddr_in *sin)); -static Code_t host_attach P((struct sockaddr_in *who, ZServerDesc_t *server)); - -#undef P - -/* - * We received a HostManager packet. process accordingly. - */ - -/*ARGSUSED*/ -Code_t -hostm_dispatch(notice, auth, who, server) - ZNotice_t *notice; - int auth; - struct sockaddr_in *who; - ZServerDesc_t *server; -{ - ZServerDesc_t *owner; - ZHostList_t *host = NULLZHLT; - char *opcode = notice->z_opcode; - Code_t retval; - -#if 0 - zdbug((LOG_DEBUG,"hm_disp")); -#endif - - host = hostm_find_host(&who->sin_addr); - if (host && host->zh_locked) - return(ZSRV_REQUEUE); - - if (notice->z_kind == HMACK) { - host_not_losing(who); - return(ZERR_NONE); - } else if (notice->z_kind != HMCTL) { -#if 0 - zdbug((LOG_DEBUG, "bogus HM packet")); -#endif - clt_ack(notice, who, AUTH_FAILED); - return(ZERR_NONE); - } - owner = hostm_find_server(&who->sin_addr); - if (!strcmp(opcode, HM_ATTACH)) { -#if 0 - zdbug((LOG_DEBUG,"attach %s",inet_ntoa(who))); -#endif - if (owner == server) { -#if 0 - zdbug((LOG_DEBUG,"no change")); -#endif - /* Same server owns him. do nothing */ - } else if (owner) { - /* He has switched servers. - he was lost but has asked server to work for him. - We need to transfer him to server */ -#if 0 - zdbug((LOG_DEBUG,"hm_disp transfer")); -#endif - hostm_transfer(host, server); - } else { - /* no owner. attach him to server. */ - if ((retval = host_attach(who, server)) - != ZERR_NONE) { - syslog(LOG_WARNING, "hattach failed: %s", - error_message(retval)); - return(retval); - } - - } - if (server == me_server) { - server_forward(notice, auth, who); - ack(notice, who); - } - } else if (!strcmp(opcode, HM_BOOT)) { -#if 0 - zdbug((LOG_DEBUG, "boot %s (server %s)", - inet_ntoa(who->sin_addr), - server->addr)); -#endif - /* Booting is just like flushing and attaching */ - if (owner) /* if owned, flush */ - hostm_flush(host, owner); - if ((retval = host_attach(who, server)) != ZERR_NONE) { - syslog(LOG_WARNING, "hattach failed: %s", - error_message(retval)); - return(retval); - } - if (server == me_server) { - server_forward(notice, auth, who); - ack(notice, who); - } - } else if (!strcmp(opcode, HM_FLUSH)) { -#if 0 - zdbug((LOG_DEBUG, "hm_flush %s (server %s)", - inet_ntoa(who->sin_addr), - server->addr)); -#endif - if (!owner) - return(ZERR_NONE); - /* flush him */ - hostm_flush(host, owner); - if (server == me_server) - server_forward(notice, auth, who); - } else if (!strcmp(opcode, HM_DETACH)) { -#if 0 - zdbug((LOG_DEBUG, "hm_detach %s",inet_ntoa(who_sin_addr))); -#endif - /* ignore it */ - } else { - syslog(LOG_WARNING, "hm_disp: unknown opcode %s",opcode); - return(ZERR_NONE); - } - return(ZERR_NONE); -} - -/* - * Flush all information about this host. Remove any losing host entries, - * deregister all the clients, flush any user locations, and remove the host - * from its server. - * The caller is responsible for informing other servers of this flush - * (if appropriate). - */ - -void -hostm_flush(host, server) - ZHostList_t *host; - ZServerDesc_t *server; -{ - register ZClientList_t *clist = NULLZCLT, *clt; - losinghost *lhp, *lhp2; - - START_CRITICAL_CODE; - - if (!host) { - syslog(LOG_WARNING, "null host flush"); - return; - } - -#if 0 - zdbug ((LOG_DEBUG,"hostm_flush %s", inet_ntoa (host->zh_addr.sin_addr))); -#endif - - if (losing_hosts) - for (lhp = losing_hosts->q_forw; - lhp != losing_hosts;) - if (lhp->lh_host == host) { - lhp2 = lhp->q_back; - timer_reset(lhp->lh_timer); - xremque(lhp); - xfree(lhp); - lhp = lhp2->q_forw; - } else - lhp = lhp->q_forw; - - if ((clist = host->zh_clients) != NULLZCLT) { - for (clt = clist->q_forw; clt != clist; clt = clist->q_forw) { - /* client_deregister frees this client & subscriptions - & locations and remque()s the client */ -#if 0 - if (zdebug) - syslog (LOG_DEBUG, "hostm_flush clt_dereg %s/%d", - inet_ntoa(host->zh_addr.sin_addr), - ntohs (clt->zclt_client->zct_sin.sin_port)); -#endif - client_deregister(clt->zclt_client, host, 1); - } - } - - uloc_hflush(&host->zh_addr.sin_addr); - host_detach(host, server); - - END_CRITICAL_CODE; - - return; -} - -/* - * send a shutdown to each of our hosts - */ - -void -hostm_shutdown() -{ - register ZHostList_t *hosts = otherservers[me_server_idx].zs_hosts; - register ZHostList_t *host; - int newserver, i; - -#if 0 - zdbug((LOG_DEBUG,"hostm_shutdown")); -#endif - if (!hosts) - return; - - for (i = 0; i < nservers; i++){ - if (i == me_server_idx) continue; - if (otherservers[i].zs_state == SERV_UP) - break; - } - if (i == nservers) /* no other servers are up */ - newserver = 0; - else - newserver = 1; - - /* kill them all */ - for (host = hosts->q_forw; - host != hosts; - host = host->q_forw) { - /* recommend a random, known up server */ - if (newserver) { - do - newserver = (int) (random() % (nservers - 1)) + 1; - while (newserver == limbo_server_idx() || - (otherservers[newserver].zs_state != SERV_UP && - otherservers[newserver].zs_state != SERV_TARDY) || - newserver == me_server_idx); - hostm_deathgram(&host->zh_addr, &otherservers[newserver]); - } else - hostm_deathgram(&host->zh_addr, NULLZSDT); - } - return; -} - - -/* - * The client on the host is not acknowledging any packets. Ping the - * host and set a timeout. - */ - -void -hostm_losing(client, host) - ZClient_t *client; - ZHostList_t *host; -{ - losinghost *newhost; - -#if 0 - zdbug((LOG_DEBUG,"losing host")); -#endif - if (!losing_hosts) { - if (!(losing_hosts = (losinghost *) - xmalloc(sizeof(losinghost)))) { - syslog(LOG_ERR, "no mem losing host"); - return; - } - losing_hosts->q_forw = losing_hosts->q_back = losing_hosts; - } - for (newhost = losing_hosts->q_forw; - newhost != losing_hosts; - newhost = newhost->q_forw) - if (newhost->lh_client == client) { -#if 0 - zdbug((LOG_DEBUG,"clt already losing")); -#endif - return; - } - if (!(newhost = (losinghost *) xmalloc(sizeof(losinghost)))) { - syslog(LOG_ERR, "no mem losing host 2"); - return; - } - - /* send a ping */ - ping(&host->zh_addr); - newhost->lh_host = host; - newhost->lh_client = client; - newhost->lh_timer = timer_set_rel(lose_timo, host_lost, (void *) newhost); - xinsque(newhost, losing_hosts); - return; -} - -/* - * The host did not respond to the ping, so we punt him - */ - -static void -host_lost(arg) - void* arg; -{ - losinghost *which = (losinghost *) arg; - ZServerDesc_t *server; - ZNotice_t notice; - struct sockaddr_in who; - Code_t retval; - char *buffer; - int len; - - START_CRITICAL_CODE; - - server = hostm_find_server(&which->lh_host->zh_addr.sin_addr); -#if 1 - zdbug ((LOG_DEBUG,"lost host %s (server %s)", - inet_ntoa(which->lh_host->zh_addr.sin_addr), - server ? server->addr : "<NONE>")); -#endif - - if (!server) { -#if 1 - zdbug((LOG_DEBUG,"no server")); -#endif - xremque(which); - xfree(which); - END_CRITICAL_CODE; - return; - } - xremque(which); - hostm_flush(which->lh_host, server); - - (void) memset((caddr_t)¬ice, 0, sizeof(notice)); - - /* tell other servers to flush this host */ - notice.z_kind = HMCTL; - notice.z_auth = 0; - notice.z_port = hm_port; - notice.z_class = ZEPHYR_CTL_CLASS; - notice.z_class_inst = ZEPHYR_CTL_HM; - notice.z_opcode = HM_FLUSH; - notice.z_sender = "HM"; - notice.z_recipient = ""; - notice.z_default_format = ""; - notice.z_num_other_fields = 0; - notice.z_message_len = 0; - - /* generate the other fields */ - retval = ZFormatNotice(¬ice, &buffer, &len, ZNOAUTH); - if (retval != ZERR_NONE) - return; - xfree(buffer); - - /* forge a from address */ - (void) memset((char *) &who, 0, sizeof(who)); - who.sin_addr.s_addr = which->lh_host->zh_addr.sin_addr.s_addr; - who.sin_port = hm_port; - who.sin_family = AF_INET; - - server_forward(¬ice, 0, &who); /* unauthentic */ - - xfree(which); - - END_CRITICAL_CODE; - - return; -} - -/* - * The host responded to the ping, so we flush the losing clients on this host. - */ - -static void -host_not_losing(who) - struct sockaddr_in *who; -{ - losinghost *lhp, *lhp2; - - if (!losing_hosts) - return; - - START_CRITICAL_CODE; - - for (lhp = losing_hosts->q_forw; - lhp != losing_hosts;) - if (lhp->lh_host->zh_addr.sin_addr.s_addr == who->sin_addr.s_addr) { - /* go back, since remque will change things */ - lhp2 = lhp->q_back; - timer_reset(lhp->lh_timer); -#if 1 - if (zdebug || 1) - syslog (LOG_DEBUG,"lost client %s/%d", - inet_ntoa(lhp->lh_client->zct_sin.sin_addr), - ntohs(lhp->lh_client->zct_sin.sin_port)); -#endif - /* deregister all subscriptions, and flush locations - associated with the client. */ -#if 0 - if (zdebug) - syslog(LOG_DEBUG,"h_not_lose clt_dereg"); -#endif - server_kill_clt(lhp->lh_client); - client_deregister(lhp->lh_client, lhp->lh_host, 1); - xremque(lhp); - xfree(lhp); - /* now that the remque adjusted the linked list, - we go forward again */ - lhp = lhp2->q_forw; - } else - lhp = lhp->q_forw; - - END_CRITICAL_CODE; - - return; -} - -/* - * A client is being de-registered, so remove it from the losing_host list, - * if it is there. - */ - -void -hostm_lose_ignore(client) - ZClient_t *client; -{ - losinghost *lhp, *lhp2; - - if (!losing_hosts) - return; - - START_CRITICAL_CODE; - - for (lhp = losing_hosts->q_forw; - lhp != losing_hosts;) - /* if client matches, remove it */ - if (lhp->lh_client == client) { - /* go back, since remque will change things */ - lhp2 = lhp->q_back; - timer_reset(lhp->lh_timer); -#if 0 - zdbug((LOG_DEBUG,"hm_l_ign client %s/%d", - inet_ntoa(client->zct_sin), - ntohs(client->zct_sin.sin_port))); -#endif - xremque(lhp); - xfree(lhp); - /* now that the remque adjusted the linked list, - we go forward again */ - lhp = lhp2->q_forw; - } else - lhp = lhp->q_forw; - - END_CRITICAL_CODE; - - return; -} - -/* - * transfer this host to server's ownership. The caller must update the - * other servers. - */ - -void -hostm_transfer(host, server) - ZHostList_t *host; - ZServerDesc_t *server; -{ - /* we need to unlink and relink him, and change the table entry */ -#if 1 - if (zdebug) - syslog (LOG_DEBUG, "hostm_transfer %s to %s", - inet_ntoa (host->zh_addr.sin_addr), server->addr); -#endif - - /* is this the same server? */ - if (hostm_find_server(&host->zh_addr.sin_addr) == server) - return; - - START_CRITICAL_CODE; - - /* remove from old server's queue */ - xremque(host); - - /* switch servers in the table */ - remove_host(host); - insert_host(host, server); - - /* insert in our queue */ - xinsque(host, server->zs_hosts); - - END_CRITICAL_CODE; - - return; -} - - -/* - * attach the host with return address in who to the server. - */ - -static Code_t -host_attach(who, server) - struct sockaddr_in *who; - ZServerDesc_t *server; -{ - register ZHostList_t *hlist; - register ZClientList_t *clist; - - START_CRITICAL_CODE; - -#if 0 - if (zdebug) - syslog (LOG_DEBUG, "host_attach %s to %s", - inet_ntoa (who->sin_addr), server->addr); -#endif - /* allocate a header */ - if (!(hlist = (ZHostList_t *) xmalloc(sizeof(ZHostList_t)))) { - syslog(LOG_WARNING, "hm_attach alloc"); - END_CRITICAL_CODE; - return(ENOMEM); - } - /* set up */ - if (!(clist = (ZClientList_t *)xmalloc(sizeof(ZClientList_t)))) { - xfree(hlist); - END_CRITICAL_CODE; - return(ENOMEM); - } - clist->zclt_client = NULLZCNT; - clist->q_forw = clist->q_back = clist; - - hlist->zh_clients = clist; - hlist->zh_addr = *who; - hlist->q_forw = hlist->q_back = hlist; - hlist->zh_locked = 0; - - /* add to table */ - insert_host(hlist, server); - - /* chain in to the end of the list */ - xinsque(hlist, server->zs_hosts->q_back); - - END_CRITICAL_CODE; - - return(ZERR_NONE); -} - -/* - * detach the host at addr from the server - * Warning: this routine assumes all the clients have already been removed - * from this host. - */ - -static void -host_detach(host, server) - register ZHostList_t *host; - ZServerDesc_t *server; -{ - ZServerDesc_t *server2; - - START_CRITICAL_CODE; - - /* undo what we did in host_attach */ - server2 = hostm_find_server (&host->zh_addr.sin_addr); - - if (server2 != server) { - syslog(LOG_WARNING, - "host_detach: wrong server: %s from %s, found %s", - inet_ntoa (host->zh_addr.sin_addr), - server->addr, - server2->addr); - END_CRITICAL_CODE; - return; - } - - - /* all the clients have already been freed */ - xfree(host->zh_clients); - - /* unchain */ - xremque(host); - - /* remove from table */ - remove_host(host); - - xfree(host); - - END_CRITICAL_CODE; - - return; -} - -/* - * Build hostmanager recipient name. - */ -static char * -hm_recipient () -{ - static char *recipient; - char *realm; - - if (recipient) - return recipient; - - realm = ZGetRealm (); - if (!realm) - realm = "???"; - recipient = (char *) xmalloc (strlen (realm) + 4); - strcpy (recipient, "hm@"); - strcat (recipient, realm); - return recipient; -} - -/* - * Send a shutdown message to the HostManager at sin, recommending him to - * use server - */ - -void -hostm_deathgram(sin, server) - struct sockaddr_in *sin; - ZServerDesc_t *server; -{ - Code_t retval; - int shutlen; - ZNotice_t shutnotice; - char *shutpack; - -#if 0 - zdbug((LOG_DEBUG,"deathgram %s",inet_ntoa(*sin))); -#endif - - /* fill in the shutdown notice */ - - shutnotice.z_kind = HMCTL; - shutnotice.z_port = sock_sin.sin_port; /* we are sending it */ - shutnotice.z_class = HM_CTL_CLASS; - shutnotice.z_class_inst = HM_CTL_SERVER; - shutnotice.z_opcode = SERVER_SHUTDOWN; - shutnotice.z_sender = HM_CTL_SERVER; - shutnotice.z_recipient = hm_recipient (); - shutnotice.z_default_format = ""; - shutnotice.z_num_other_fields = 0; - - if (server) { - shutnotice.z_message = server->addr; - shutnotice.z_message_len = strlen(shutnotice.z_message) + 1; -#if 0 - zdbug((LOG_DEBUG, "suggesting %s",shutnotice.z_message)); -#endif - } else { - shutnotice.z_message = NULL; - shutnotice.z_message_len = 0; - } - - if ((retval = ZFormatNotice(&shutnotice, - &shutpack, - &shutlen, - ZNOAUTH)) != ZERR_NONE) { - syslog(LOG_ERR, "hm_shut format: %s",error_message(retval)); - return; - } - if ((retval = ZSetDestAddr(sin)) != ZERR_NONE) { - syslog(LOG_WARNING, "hm_shut set addr: %s", - error_message(retval)); - xfree(shutpack); /* free allocated storage */ - return; - } - /* don't wait for ack! */ - if ((retval = ZSendPacket(shutpack, shutlen, 0)) != ZERR_NONE) { - syslog(LOG_WARNING, "hm_shut xmit: %s", error_message(retval)); - xfree(shutpack); /* free allocated storage */ - return; - } - xfree(shutpack); /* free allocated storage */ - return; -} - -/* - * Send a ping to the HostManager at sin - */ - -static void -ping(sin) - struct sockaddr_in *sin; -{ - Code_t retval; - int shutlen; - ZNotice_t shutnotice; - char *shutpack; - -#if 0 - zdbug((LOG_DEBUG,"ping %s",inet_ntoa(*sin))); -#endif - - /* fill in the shutdown notice */ - - shutnotice.z_kind = HMCTL; - shutnotice.z_port = sock_sin.sin_port; - shutnotice.z_class = HM_CTL_CLASS; - shutnotice.z_class_inst = HM_CTL_SERVER; - shutnotice.z_opcode = SERVER_PING; - shutnotice.z_sender = HM_CTL_SERVER; - shutnotice.z_recipient = hm_recipient (); - shutnotice.z_message = NULL; - shutnotice.z_message_len = 0; - shutnotice.z_default_format = ""; - shutnotice.z_num_other_fields = 0; - - if ((retval = ZFormatNotice(&shutnotice, - &shutpack, - &shutlen, - ZNOAUTH)) != ZERR_NONE) { - syslog(LOG_ERR, "hm_ping format: %s",error_message(retval)); - return; - } - if ((retval = ZSetDestAddr(sin)) != ZERR_NONE) { - syslog(LOG_WARNING, "hm_ping set addr: %s", - error_message(retval)); - xfree(shutpack); /* free allocated storage */ - return; - } - /* don't wait for ack */ - if ((retval = ZSendPacket(shutpack, shutlen, 0)) != ZERR_NONE) { - syslog(LOG_WARNING, "hm_ping xmit: %s", error_message(retval)); - xfree(shutpack); /* free allocated storage */ - return; - } - xfree(shutpack); /* free allocated storage */ - return; -} - -/* - * Routines for maintaining the host array. - */ - -/* - * Binary search on the host table to find this host. - */ - -ZHostList_t * -hostm_find_host(addr) - struct in_addr *addr; -{ - register int i, rlo, rhi; - - if (!all_hosts) - return(NULLZHLT); - - /* i is the current host we are checking */ - /* rlo is the lowest we will still check, rhi is the highest we will - still check */ - - i = num_hosts >> 1; /* start in the middle */ - rlo = 0; - rhi = num_hosts - 1; /* first index is 0 */ - - while ((all_hosts[i].host)->zh_addr.sin_addr.s_addr != addr->s_addr) { - if ((all_hosts[i].host)->zh_addr.sin_addr.s_addr < addr->s_addr) - rlo = i + 1; - else - rhi = i - 1; - if (rhi - rlo < 0) - return(NULLZHLT); - i = (rhi + rlo) >> 1; /* split the diff */ - } - return(all_hosts[i].host); -} - -/* - * Binary search on the host table to find this host's server. - */ - -ZServerDesc_t * -hostm_find_server(addr) - struct in_addr *addr; -{ - register int i, rlo, rhi; - - if (!all_hosts) - return(NULLZSDT); - - /* i is the current host we are checking */ - /* rlo is the lowest we will still check, rhi is the highest we will - still check */ - - i = num_hosts >> 1; /* start in the middle */ - rlo = 0; - rhi = num_hosts - 1; /* first index is 0 */ - - while ((all_hosts[i].host)->zh_addr.sin_addr.s_addr != addr->s_addr) { - if ((all_hosts[i].host)->zh_addr.sin_addr.s_addr < addr->s_addr) - rlo = i + 1; - else - rhi = i - 1; - if (rhi - rlo < 0) - return(NULLZSDT); - i = (rhi + rlo) >> 1; /* split the diff */ - } - return(&otherservers[all_hosts[i].server_index]); -} - -/* - * Insert the host and server into the sorted array of hosts. - */ - -static void -insert_host(host, server) - ZHostList_t *host; - ZServerDesc_t *server; -{ - struct hostlist *oldlist; - register int i = 0; - -#if 0 - zdbug ((LOG_DEBUG,"insert_host %s %s", - inet_ntoa(host->zh_addr.sin_addr), server->addr)); -#endif - if (hostm_find_host(&host->zh_addr.sin_addr)) - return; - - START_CRITICAL_CODE; - - num_hosts++; - oldlist = all_hosts; - - if (!(all_hosts = (struct hostlist *) xmalloc(num_hosts * sizeof(struct hostlist)))) { - syslog(LOG_CRIT, "insert_host: nomem"); - abort(); - } - - if (!oldlist) { /* this is the first */ - all_hosts[0].host = host; - all_hosts[0].server_index = server - otherservers; - END_CRITICAL_CODE; - return; - } - - /* copy old pointers */ - while ((i < (num_hosts - 1)) && - ((oldlist[i].host)->zh_addr.sin_addr.s_addr < host->zh_addr.sin_addr.s_addr)) { - all_hosts[i] = oldlist[i]; - i++; - } - /* add this one */ - all_hosts[i].host = host; - all_hosts[i++].server_index = server - otherservers; - - /* copy the rest */ - while (i < num_hosts) { - all_hosts[i] = oldlist[i - 1]; - i++; - } - xfree(oldlist); - - END_CRITICAL_CODE; - -#if defined (DEBUG) && 0 - if (zdebug) { - register int i = 0; - for (i = 0; i < num_hosts; i++) - syslog(LOG_DEBUG, "%d: %s %s",i, - inet_ntoa ((all_hosts[i].host)->zh_addr.sin_addr), - otherservers[all_hosts[i].server_index]->addr); - } -#endif - return; -} - -/* - * remove the host from the array of known hosts. - */ - -static void -remove_host(host) - ZHostList_t *host; -{ - struct hostlist *oldlist; - register int i = 0; - -#if 0 - zdbug((LOG_DEBUG,"remove_host %s", inet_ntoa(host->zh_addr.sin_addr))); -#endif - if (!hostm_find_host(&host->zh_addr.sin_addr)) - return; - - START_CRITICAL_CODE; - - if (--num_hosts == 0) { -#if 0 - zdbug((LOG_DEBUG,"last host")); -#endif - xfree (all_hosts); - all_hosts = NULLHLT; - END_CRITICAL_CODE; - return; - } - - oldlist = all_hosts; - - if (!(all_hosts = (struct hostlist *) xmalloc(num_hosts * sizeof(struct hostlist)))) { - syslog(LOG_CRIT, "remove_host: nomem"); - abort(); - } - - /* copy old pointers */ - while (i < num_hosts && (oldlist[i].host)->zh_addr.sin_addr.s_addr < host->zh_addr.sin_addr.s_addr) { - all_hosts[i] = oldlist[i]; - i++; - } - - i++; /* skip over this one */ - - /* copy the rest */ - while (i <= num_hosts) { - all_hosts[i - 1] = oldlist[i]; - i++; - } - xfree (oldlist); - - END_CRITICAL_CODE; - - return; -} - -/* - * Assumes that SIGFPE is blocked when called; this is true if called from a - * signal handler - */ - -void -hostm_dump_hosts(fp) - FILE *fp; -{ - register int i; - for (i = 0; i < num_hosts; i++) { - (void) fprintf(fp, "%s/%d:\n", - inet_ntoa((all_hosts[i].host)->zh_addr.sin_addr), - all_hosts[i].server_index); - client_dump_clients(fp,(all_hosts[i].host)->zh_clients); - } - return; -} - -/* - * Readjust server-array indices according to the supplied new vector. - */ - -void -hostm_renumber_servers (srv) - int *srv; -{ - int i; - for (i = 0; i < num_hosts; i++) { - int idx = srv[all_hosts[i].server_index]; - if (idx < 0) { - syslog (LOG_ERR, "hostm_renumber_servers error: [%d] = %d", - all_hosts[i].server_index, idx); - idx = 0; - } - all_hosts[i].server_index = idx; - } -} |