summaryrefslogtreecommitdiff
path: root/zhm
diff options
context:
space:
mode:
authorGravatar Greg Hudson <ghudson@mit.edu>1997-09-14 18:12:16 +0000
committerGravatar Greg Hudson <ghudson@mit.edu>1997-09-14 18:12:16 +0000
commitce6018836c422c86a729ba39fe5433ec11b87b02 (patch)
treecc2e6601489384fcf41e0565e8906822897b46c8 /zhm
parentac16f380e349fa39ec7e26bccb5456cb300006a5 (diff)
Pull in sources from zephyr locker. See /mit/zephyr/repository for
detailed change information.
Diffstat (limited to 'zhm')
-rw-r--r--zhm/Imakefile27
-rw-r--r--zhm/Makefile.in48
-rw-r--r--zhm/TODO9
-rw-r--r--zhm/queue.c383
-rw-r--r--zhm/timer.c257
-rw-r--r--zhm/timer.h56
-rw-r--r--zhm/zhm.c576
-rw-r--r--zhm/zhm.h96
-rw-r--r--zhm/zhm_client.c125
-rw-r--r--zhm/zhm_server.c216
10 files changed, 1021 insertions, 772 deletions
diff --git a/zhm/Imakefile b/zhm/Imakefile
deleted file mode 100644
index f008e04..0000000
--- a/zhm/Imakefile
+++ /dev/null
@@ -1,27 +0,0 @@
-/**/# Copyright 1988, 1993 Massachusetts Institute of Technology.
-/**/#
-/**/# For copying and distribution information, see the file
-/**/# "mit-copyright.h".
-/**/#
-/**/# $Source$
-/**/# $Author$
-/**/# $Zephyr: /mit/zephyr/src/zhm/RCS/Imakefile,v 1.8 91/03/21 11:38:01 raeburn Exp $
-/**/#
-
-#if defined(SYSLOG_COMPAT42)
-SOBJS= ../clients/syslogd/syslog.o
-SINCLUDE= -I../clients/syslogd
-#endif
-
-#ifdef __NetBSD__
-OSLIBS=-lcompat /* for insque() */
-#endif
-
-SRCS= zhm.c zhm_server.c zhm_client.c queue.c
-OBJS= zhm.o zhm_server.o zhm_client.o queue.o
-
-XDEFS= $(SINCLUDE) -DPIDFILE=\"$(ZPIDDIR)/zhm.pid\"
-
-SimpleProgram(zhm,$(OBJS) $(SOBJS) $(ZLIB),$(ZLIBS) $(OSLIBS),$(ATHRETCDIR))
-install_man(zhm.8,zhm.8)
-create_depend($(SRCS))
diff --git a/zhm/Makefile.in b/zhm/Makefile.in
new file mode 100644
index 0000000..d591586
--- /dev/null
+++ b/zhm/Makefile.in
@@ -0,0 +1,48 @@
+SHELL = /bin/sh
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+datadir=@datadir@
+confdir=@confdir@
+sbindir=@sbindir@
+lsbindir=@lsbindir@
+
+includedir=${prefix}/include
+mandir=${prefix}/man
+libdir=${exec_prefix}/lib
+
+srcdir=@srcdir@
+top_srcdir=@top_srcdir@
+BUILDTOP=..
+VPATH=@srcdir@
+CC=@CC@
+INSTALL=@INSTALL@
+
+DEBUG=-O
+CFLAGS=${DEBUG} -DCONFDIR=\"${confdir}\" -I${top_srcdir}/h -I${BUILDTOP}/h \
+ @CPPFLAGS@
+LDFLAGS=${DEBUG} -L${BUILDTOP}/lib/zephyr @ET_LDFLAGS@ @LDFLAGS@
+LIBS=-lzephyr @LIBS@ -lcom_err
+
+OBJS= timer.o queue.o zhm.o zhm_client.o zhm_server.o
+
+all: zhm
+
+zhm: ${OBJS} ${BUILDTOP}/lib/zephyr/libzephyr.a @ETDEP@
+ ${CC} ${LDFLAGS} -o $@ ${OBJS} ${LIBS}
+
+check:
+
+install: zhm
+ ${INSTALL} -m 755 -s zhm ${DESTDIR}${lsbindir}
+ ${INSTALL} -m 644 ${srcdir}/zhm.8 ${DESTDIR}${mandir}/man8
+
+clean:
+ rm -f ${OBJS} zhm
+
+${OBJS}: zhm.h timer.h ${top_srcdir}/h/internal.h ${top_srcdir}/h/sysdep.h
+${OBJS}: ${BUILDTOP}/h/config.h ${BUILDTOP}/h/zephyr/zephyr.h
+${OBJS}: ${BUILDTOP}/h/zephyr/zephyr_err.h
+
+.PHONY: all check install clean
+
diff --git a/zhm/TODO b/zhm/TODO
deleted file mode 100644
index 4562044..0000000
--- a/zhm/TODO
+++ /dev/null
@@ -1,9 +0,0 @@
-
-Search for all occurences of (void) typecasting, and see whether I
-should be checking return values. Make sure all mallocs are checked
-for return values.
-
-Set system up to handle SERVNAK returns if we cannot reach a server.
-
-Set to handle emergency notices.
-
diff --git a/zhm/queue.c b/zhm/queue.c
index fd87546..5e0ca3a 100644
--- a/zhm/queue.c
+++ b/zhm/queue.c
@@ -20,249 +20,224 @@ static char rcsid_queue_c[] = "$Header$";
#endif /* lint */
typedef struct _Queue {
- long timeout;
- int retries;
- ZNotice_t z_notice;
- caddr_t z_packet;
- struct sockaddr_in reply;
+ Timer *timer;
+ int retries;
+ ZNotice_t notice;
+ caddr_t packet;
+ struct sockaddr_in reply;
+ struct _Queue *next, **prev_p;
} Queue;
-struct _qelem {
- struct _qelem *q_forw;
- struct _qelem *q_back;
- Queue *q_data;
-};
+static Queue *hm_queue;
+static int retransmits_enabled = 0;
-typedef struct _qelem Qelem;
-
-Qelem hm_queue = { &hm_queue, &hm_queue, NULL }, *is_in_queue();
+static Queue *find_notice_in_queue __P((ZNotice_t *notice));
+static Code_t dump_queue __P((void));
+static void queue_timeout __P((void *arg));
int rexmit_times[] = { 2, 2, 4, 4, 8, -1 };
-extern long time();
-extern int timeout_type;
+#ifdef DEBUG
+Code_t dump_queue();
+#endif
void init_queue()
{
- while (hm_queue.q_forw != &hm_queue) {
- free(hm_queue.q_forw->q_data->z_packet);
- free((char *)hm_queue.q_forw->q_data);
- remque(hm_queue.q_forw);
- free((char *)hm_queue.q_forw);
- }
-
- hm_queue.q_forw = hm_queue.q_back = &hm_queue;
- hm_queue.q_data = NULL;
- DPR ("Queue initialized and flushed.\n");
+ Queue *q;
+
+ while (hm_queue) {
+ q = hm_queue;
+ if (q->timer)
+ timer_reset(q->timer);
+ free(q->packet);
+ hm_queue = q->next;
+ free(q);
+ }
+
+ DPR("Queue initialized and flushed.\n");
}
Code_t add_notice_to_queue(notice, packet, repl, len)
-ZNotice_t *notice;
-caddr_t packet;
-struct sockaddr_in *repl;
-int len;
+ ZNotice_t *notice;
+ char * packet;
+ struct sockaddr_in *repl;
+ int len;
{
- Qelem *elem;
- Queue *entry;
-
- DPR ("Adding notice to queue...\n");
- if (!is_in_queue(notice)) {
- elem = (Qelem *)malloc(sizeof(Qelem));
- entry = (Queue *)malloc(sizeof(Queue));
- entry->timeout = time((time_t *)0) + rexmit_times[0];
- entry->retries = 0;
- entry->z_packet = (char *)malloc(Z_MAXPKTLEN);
- (void) memcpy(entry->z_packet, packet, Z_MAXPKTLEN);
- if (ZParseNotice(entry->z_packet, len, &entry->z_notice)
- != ZERR_NONE) {
- syslog(LOG_ERR, "ZParseNotice failed, but succeeded before");
- free(entry->z_packet);
- } else {
- entry->reply = *repl;
- elem->q_data = entry;
- elem->q_forw = elem;
- elem->q_back = elem;
- insque(elem, hm_queue.q_back);
- }
- }
-#ifdef DEBUG
- if (!is_in_queue(notice))
- return(ZERR_NONOTICE);
- else
-#endif /* DEBUG */
- return(ZERR_NONE);
+ Queue *entry;
+
+ DPR("Adding notice to queue...\n");
+ if (!find_notice_in_queue(notice)) {
+ entry = (Queue *) malloc(sizeof(Queue));
+ entry->retries = 0;
+ entry->packet = (char *) malloc(Z_MAXPKTLEN);
+ memcpy(entry->packet, packet, Z_MAXPKTLEN);
+ if (ZParseNotice(entry->packet, len, &entry->notice) != ZERR_NONE) {
+ syslog(LOG_ERR, "ZParseNotice failed, but succeeded before");
+ free(entry->packet);
+ } else {
+ entry->reply = *repl;
+ LIST_INSERT(&hm_queue, entry);
+ }
+ entry->timer = (retransmits_enabled) ?
+ timer_set_rel(rexmit_times[0], queue_timeout, entry) : NULL;
+ }
+ return(ZERR_NONE);
}
Code_t remove_notice_from_queue(notice, kind, repl)
-ZNotice_t *notice;
-ZNotice_Kind_t *kind;
-struct sockaddr_in *repl;
+ ZNotice_t *notice;
+ ZNotice_Kind_t *kind;
+ struct sockaddr_in *repl;
{
- Qelem *elem;
-
- DPR ("Removing notice from queue...\n");
- if ((elem = is_in_queue(notice)) == NULL)
- return(ZERR_NONOTICE);
- else {
- *kind = elem->q_data->z_notice.z_kind;
- *repl = elem->q_data->reply;
- free(elem->q_data->z_packet);
- free((char *)elem->q_data);
- remque(elem);
- free((char *)elem);
- if (hm_queue.q_forw == &hm_queue)
- (void)alarm(0);
+ Queue *entry;
+
+ DPR("Removing notice from queue...\n");
+ entry = find_notice_in_queue(notice);
+ if (entry == NULL)
+ return(ZERR_NONOTICE);
+
+ *kind = entry->notice.z_kind;
+ *repl = entry->reply;
+ timer_reset(entry->timer);
+ free(entry->packet);
+ LIST_DELETE(entry);
#ifdef DEBUG
- dump_queue();
+ dump_queue();
#endif /* DEBUG */
- return(ZERR_NONE);
- }
+ return(ZERR_NONE);
}
+/* We have a server; transmit all of our packets. */
void retransmit_queue(sin)
-struct sockaddr_in *sin;
+ struct sockaddr_in *sin;
{
- Qelem *srch;
- Code_t ret;
+ Queue *entry;
+ Code_t ret;
+
+ DPR("Retransmitting queue to new server...\n");
+ ret = ZSetDestAddr(sin);
+ if (ret != ZERR_NONE) {
+ Zperr (ret);
+ com_err("queue", ret, "setting destination");
+ }
+ for (entry = hm_queue; entry; entry = entry->next) {
+ DPR("notice:\n");
+ DPR2("\tz_kind: %d\n", entry->notice.z_kind);
+ DPR2("\tz_port: %u\n", ntohs(entry->notice.z_port));
+ DPR2("\tz_class: %s\n", entry->notice.z_class);
+ DPR2("\tz_clss_inst: %s\n", entry->notice.z_class_inst);
+ DPR2("\tz_opcode: %s\n", entry->notice.z_opcode);
+ DPR2("\tz_sender: %s\n", entry->notice.z_sender);
+ DPR2("\tz_recip: %s\n", entry->notice.z_recipient);
+ ret = send_outgoing(&entry->notice);
+ if (ret != ZERR_NONE) {
+ Zperr(ret);
+ com_err("queue", ret, "sending raw notice");
+ }
+ entry->timer = timer_set_rel(rexmit_times[0], queue_timeout, entry);
+ entry->retries = 0;
+ }
+ retransmits_enabled = 1;
+}
- DPR ("Retransmitting queue to new server...\n");
- if ((ret = ZSetDestAddr(sin)) != ZERR_NONE) {
- Zperr (ret);
- com_err("queue", ret, "setting destination");
- }
- if ((srch = hm_queue.q_forw) != &hm_queue) {
- do {
- DPR ("notice:\n");
- DPR2 ("\tz_kind: %d\n", srch->q_data->z_notice.z_kind);
- DPR2 ("\tz_port: %u\n",
- ntohs(srch->q_data->z_notice.z_port));
- DPR2 ("\tz_class: %s\n", srch->q_data->z_notice.z_class);
- DPR2 ("\tz_clss_inst: %s\n",
- srch->q_data->z_notice.z_class_inst);
- DPR2 ("\tz_opcode: %s\n", srch->q_data->z_notice.z_opcode);
- DPR2 ("\tz_sender: %s\n", srch->q_data->z_notice.z_sender);
- DPR2 ("\tz_recip: %s\n", srch->q_data->z_notice.z_recipient);
- if ((ret = send_outgoing(&srch->q_data->z_notice))
- != ZERR_NONE) {
- Zperr (ret);
- com_err("queue", ret, "sending raw notice");
- }
- srch->q_data->timeout = time(0) + rexmit_times[0];
- srch->q_data->retries = 0;
- srch = srch->q_forw;
- } while (srch != &hm_queue);
- timeout_type = NOTICES;
- (void)alarm(rexmit_times[0]);
- }
+/* We lost our server; nuke all of our timers. */
+void disable_queue_retransmits()
+{
+ Queue *entry;
+
+ for (entry = hm_queue; entry; entry = entry->next) {
+ if (entry->timer)
+ timer_reset(entry->timer);
+ entry->timer = NULL;
+ }
+ retransmits_enabled = 0;
}
#ifdef DEBUG
-Code_t dump_queue()
+static Code_t dump_queue()
{
- Qelem *srch;
- caddr_t mp;
- int ml;
-
- DPR ("Dumping queue...\n");
- if ((srch = hm_queue.q_forw) == &hm_queue)
- printf("Queue is empty.\n");
- else do {
- printf("notice:\n");
- printf("\tz_kind: %d\n", srch->q_data->z_notice.z_kind);
- printf("\tz_port: %u\n", ntohs(srch->q_data->z_notice.z_port));
- printf("\tz_class: %s\n", srch->q_data->z_notice.z_class);
- printf("\tz_clss_inst: %s\n", srch->q_data->z_notice.z_class_inst);
- printf("\tz_opcode: %s\n", srch->q_data->z_notice.z_opcode);
- printf("\tz_sender: %s\n", srch->q_data->z_notice.z_sender);
- printf("\tz_recip: %s\n", srch->q_data->z_notice.z_recipient);
- printf("\tMessage:\n");
- mp = srch->q_data->z_notice.z_message;
- for (ml = strlen(mp)+1;
- ml <= srch->q_data->z_notice.z_message_len; ml++) {
- printf("\t%s\n", mp);
- mp += strlen(mp)+1;
- ml += strlen(mp);
- }
- srch = srch->q_forw;
- } while (srch != &hm_queue);
+ Queue *entry;
+ caddr_t mp;
+ int ml;
+
+ DPR("Dumping queue...\n");
+ if (!hm_queue) {
+ printf("Queue is empty.\n");
+ return;
+ }
+
+ for (entry = hm_queue; entry; entry = entry->next) {
+ printf("notice:\n");
+ printf("\tz_kind: %d\n", entry->notice.z_kind);
+ printf("\tz_port: %u\n", ntohs(entry->notice.z_port));
+ printf("\tz_class: %s\n", entry->notice.z_class);
+ printf("\tz_clss_inst: %s\n", entry->notice.z_class_inst);
+ printf("\tz_opcode: %s\n", entry->notice.z_opcode);
+ printf("\tz_sender: %s\n", entry->notice.z_sender);
+ printf("\tz_recip: %s\n", entry->notice.z_recipient);
+ printf("\tMessage:\n");
+ mp = entry->notice.z_message;
+ for (ml = strlen(mp) + 1; ml <= entry->notice.z_message_len; ml++) {
+ printf("\t%s\n", mp);
+ mp += strlen(mp)+1;
+ ml += strlen(mp);
+ }
+ }
}
#endif /* DEBUG */
int queue_len()
{
- int length = 0;
- Qelem *srch;
+ int length = 0;
+ Queue *entry;
- if ((srch = hm_queue.q_forw) != &hm_queue) {
- do {
- length++;
- srch = srch->q_forw;
- } while (srch != &hm_queue);
- }
- return(length);
+ for (entry = hm_queue; entry; entry = entry->next)
+ length++;
+ return length;
}
-Qelem *is_in_queue(notice)
-ZNotice_t *notice;
+static Queue *find_notice_in_queue(notice)
+ ZNotice_t *notice;
{
- Qelem *srch;
+ Queue *entry;
- srch = hm_queue.q_forw;
- if (srch == &hm_queue)
- return(NULL);
- do {
- if (ZCompareUID(&(srch->q_data->z_notice.z_uid), &(notice->z_uid)))
- return(srch);
- srch = srch->q_forw;
- } while (srch != &hm_queue);
- return(NULL);
+ for (entry = hm_queue; entry; entry = entry->next) {
+ if (ZCompareUID(&entry->notice.z_uid, &notice->z_uid))
+ return entry;
+ }
+ return NULL;
}
-void resend_notices(sin)
-struct sockaddr_in *sin;
+static void queue_timeout(arg)
+ void *arg;
{
- Qelem *srch;
- Code_t ret;
-
- DPR ("Resending notices...\n");
- if ((ret = ZSetDestAddr(sin)) != ZERR_NONE) {
- Zperr(ret);
- com_err("queue", ret, "setting destination");
- }
- if ((srch = hm_queue.q_forw) == &hm_queue) {
- syslog (LOG_INFO, "No notices, shouldn't have happened!");
- } else do {
- if (srch->q_data->timeout <= time((time_t *)0)) {
- srch->q_data->retries++;
- if (rexmit_times[srch->q_data->retries] == -1) {
- new_server((char *)NULL);
- break;
- } else {
- DPR ("notice:\n");
- DPR2 ("\tz_kind: %d\n", srch->q_data->z_notice.z_kind);
- DPR2 ("\tz_port: %u\n",
- ntohs(srch->q_data->z_notice.z_port));
- DPR2 ("\tz_class: %s\n",
- srch->q_data->z_notice.z_class);
- DPR2 ("\tz_clss_inst: %s\n",
- srch->q_data->z_notice.z_class_inst);
- DPR2 ("\tz_opcode: %s\n",
- srch->q_data->z_notice.z_opcode);
- DPR2 ("\tz_sender: %s\n",
- srch->q_data->z_notice.z_sender);
- DPR2 ("\tz_recip: %s\n",
- srch->q_data->z_notice.z_recipient);
- if ((ret = send_outgoing(&srch->q_data->z_notice))
- != ZERR_NONE) {
- Zperr(ret);
- com_err("queue", ret, "sending raw notice");
- }
- srch->q_data->timeout = time((time_t *)0) +
- rexmit_times[srch->q_data->retries];
- }
- srch = srch->q_forw;
- }
- } while (srch != &hm_queue);
- if (timeout_type == NOTICES)
- (void)alarm(rexmit_times[0]);
+ Queue *entry = (Queue *) arg;
+ Code_t ret;
+
+ ret = ZSetDestAddr(&serv_sin);
+ if (ret != ZERR_NONE) {
+ Zperr(ret);
+ com_err("queue", ret, "setting destination");
+ }
+ entry->retries++;
+ if (rexmit_times[entry->retries] == -1) {
+ new_server(NULL);
+ return;
+ }
+ DPR("Resending notice:\n");
+ DPR2("\tz_kind: %d\n", entry->notice.z_kind);
+ DPR2("\tz_port: %u\n", ntohs(entry->notice.z_port));
+ DPR2("\tz_class: %s\n", entry->notice.z_class);
+ DPR2("\tz_clss_inst: %s\n", entry->notice.z_class_inst);
+ DPR2("\tz_opcode: %s\n", entry->notice.z_opcode);
+ DPR2("\tz_sender: %s\n", entry->notice.z_sender);
+ DPR2("\tz_recip: %s\n", entry->notice.z_recipient);
+ ret = send_outgoing(&entry->notice);
+ if (ret != ZERR_NONE) {
+ Zperr(ret);
+ com_err("queue", ret, "sending raw notice");
+ }
+ entry->timer = timer_set_rel(rexmit_times[entry->retries], queue_timeout,
+ entry);
}
+
diff --git a/zhm/timer.c b/zhm/timer.c
new file mode 100644
index 0000000..8fb68e5
--- /dev/null
+++ b/zhm/timer.c
@@ -0,0 +1,257 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains functions for managing multiple timeouts.
+ *
+ * Created by: John T. Kohl
+ * Derived from timer_manager_ by Ken Raeburn
+ *
+ * $Source$
+ * $Author$
+ *
+ */
+
+#include "internal.h"
+#include "timer.h"
+
+#ifndef SABER
+#ifndef lint
+static const char rcsid[] =
+"$Id$";
+#endif /* lint */
+#endif /* SABER */
+
+/*
+ * timer_manager_ -- routines for handling timers in login_shell
+ * (and elsewhere)
+ *
+ * Copyright 1986 Student Information Processing Board,
+ * Massachusetts Institute of Technology
+ *
+ * written by Ken Raeburn
+
+ Permission to use, copy, modify, and distribute this
+ software and its documentation for any purpose and without
+ fee is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting
+ documentation, and that the name of M.I.T. and the Student
+ Information Processing Board not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+ M.I.T. and the Student Information Processing Board
+ make no representations about the suitability of
+ this software for any purpose. It is provided "as is"
+ without express or implied warranty.
+
+ */
+
+
+/*
+ * External functions:
+ *
+ * Timer *timer_set_rel (time_rel, proc, arg)
+ * long time_rel;
+ * void (*proc)();
+ * caddr_t arg;
+ * Timer *timer_set_abs (time_abs, proc, arg)
+ * long time_abs;
+ * void (*proc)();
+ * caddr_t arg;
+ *
+ * void timer_reset(tmr)
+ * Timer *tmr;
+ *
+ * void timer_process()
+ *
+ */
+
+/* DELTA is just an offset to keep the size a bit less than a power
+ * of two. It's measured in pointers, so it's 32 bytes on most
+ * systems. */
+#define DELTA 8
+#define INITIAL_HEAP_SIZE (1024 - DELTA)
+
+/* We have three operations which we need to be able to perform
+ * quickly: adding a timer, deleting a timer given a pointer to
+ * it, and determining which timer will be the next to go off. A
+ * heap is an ideal data structure for these purposes, so we use
+ * one. The heap is an array of pointers to timers, and each timer
+ * knows the position of its pointer in the heap.
+ *
+ * Okay, what is the heap, exactly? It's a data structure,
+ * represented as an array, with the invariant condition that
+ * the timeout of heap[i] is less than or equal to the timeout of
+ * heap[i * 2 + 1] and heap[i * 2 + 2] (assuming i * 2 + 1 and
+ * i * 2 + 2 are valid * indices). An obvious consequence of this
+ * is that heap[0] has the lowest timer value, so finding the first
+ * timer to go off is easy. We say that an index i has "children"
+ * i * 2 + 1 and i * 2 + 1, and the "parent" (i - 1) / 2.
+ *
+ * To add a timer to the heap, we start by adding it to the end, and
+ * then keep swapping it with its parent until it has a parent with
+ * a timer value less than its value. With a little bit of thought,
+ * you can see that this preserves the heap property on all indices
+ * of the array.
+ *
+ * To delete a timer at position i from the heap, we discard it and
+ * fill in its position with the last timer in the heap. In order
+ * to restore the heap, we have to consider two cases: the timer
+ * value at i is less than that of its parent, or the timer value at
+ * i is greater than that of one of its children. In the first case,
+ * we propagate the timer at i up the tree, swapping it with its
+ * parent, until the heap is restored; in the second case, we
+ * propagate the timer down the tree, swapping it with its least
+ * child, until the heap is restored. */
+
+/* In order to ensure that the back pointers from timers are consistent
+ * with the heap pointers, all heap assignments should be done with the
+ * HEAP_ASSIGN() macro, which sets the back pointer and updates the
+ * heap at the same time. */
+#define PARENT(i) (((i) - 1) / 2)
+#define CHILD1(i) ((i) * 2 + 1)
+#define CHILD2(i) ((i) * 2 + 2)
+#define TIME(i) (heap[i]->abstime)
+#define HEAP_ASSIGN(pos, tmr) ((heap[pos] = (tmr))->heap_pos = (pos))
+
+static Timer **heap;
+static int num_timers = 0;
+static int heap_size = 0;
+
+static void timer_botch __P((void*));
+static Timer *add_timer __P((Timer *));
+
+Timer *timer_set_rel(time_rel, proc, arg)
+ long time_rel;
+ void (*proc) __P((void *));
+ void *arg;
+{
+ Timer *new_t;
+
+ new_t = (Timer *) malloc(sizeof(*new_t));
+ if (new_t == NULL)
+ return(NULL);
+ new_t->abstime = time_rel + time(NULL);
+ new_t->func = proc;
+ new_t->arg = arg;
+ return add_timer(new_t);
+}
+
+void
+timer_reset(tmr)
+ Timer *tmr;
+{
+ int pos, min;
+
+ /* Free the timer, saving its heap position. */
+ pos = tmr->heap_pos;
+ free(tmr);
+
+ if (pos != num_timers - 1) {
+ /* Replace the timer with the last timer in the heap and
+ * restore the heap, propagating the timer either up or
+ * down, depending on which way it violates the heap
+ * property to insert the last timer in place of the
+ * deleted timer. */
+ if (pos > 0 && TIME(num_timers - 1) < TIME(PARENT(pos))) {
+ do {
+ HEAP_ASSIGN(pos, heap[PARENT(pos)]);
+ pos = PARENT(pos);
+ } while (pos > 0 && TIME(num_timers - 1) < TIME(PARENT(pos)));
+ HEAP_ASSIGN(pos, heap[num_timers - 1]);
+ } else {
+ while (CHILD2(pos) < num_timers) {
+ min = num_timers - 1;
+ if (TIME(CHILD1(pos)) < TIME(min))
+ min = CHILD1(pos);
+ if (TIME(CHILD2(pos)) < TIME(min))
+ min = CHILD2(pos);
+ HEAP_ASSIGN(pos, heap[min]);
+ pos = min;
+ }
+ if (pos != num_timers - 1)
+ HEAP_ASSIGN(pos, heap[num_timers - 1]);
+ }
+ }
+ num_timers--;
+}
+
+
+#define set_timeval(t,s) ((t).tv_sec=(s),(t).tv_usec=0,(t))
+
+static Timer *
+add_timer(new)
+ Timer *new;
+{
+ int pos;
+
+ /* Create or resize the heap as necessary. */
+ if (heap_size == 0) {
+ heap_size = INITIAL_HEAP_SIZE;
+ heap = (Timer **) malloc(heap_size * sizeof(Timer *));
+ } else if (num_timers >= heap_size) {
+ heap_size = heap_size * 2 + DELTA;
+ heap = (Timer **) realloc(heap, heap_size * sizeof(Timer *));
+ }
+ if (!heap) {
+ free(new);
+ return NULL;
+ }
+
+ /* Insert the Timer *into the heap. */
+ pos = num_timers;
+ while (pos > 0 && new->abstime < TIME(PARENT(pos))) {
+ HEAP_ASSIGN(pos, heap[PARENT(pos)]);
+ pos = PARENT(pos);
+ }
+ HEAP_ASSIGN(pos, new);
+ num_timers++;
+
+ return new;
+}
+
+void
+timer_process()
+{
+ Timer *t;
+ timer_proc func;
+ void *arg;
+ int valid = 0;
+
+ if (num_timers == 0 || heap[0]->abstime > time(NULL))
+ return;
+
+ /* Remove the first timer from the heap, remembering its
+ * function and argument. */
+ t = heap[0];
+ func = t->func;
+ arg = t->arg;
+ t->func = timer_botch;
+ t->arg = NULL;
+ timer_reset(t);
+
+ /* Run the function. */
+ func(arg);
+}
+
+struct timeval *
+timer_timeout(tvbuf)
+ struct timeval *tvbuf;
+{
+ if (num_timers > 0) {
+ tvbuf->tv_sec = heap[0]->abstime - time(NULL);
+ if (tvbuf->tv_sec < 0)
+ tvbuf->tv_sec = 0;
+ tvbuf->tv_usec = 0;
+ return tvbuf;
+ } else {
+ return NULL;
+ }
+}
+
+static void
+timer_botch(arg)
+ void *arg;
+{
+ syslog(LOG_CRIT, "timer botch\n");
+ abort();
+}
+
diff --git a/zhm/timer.h b/zhm/timer.h
new file mode 100644
index 0000000..42c0081
--- /dev/null
+++ b/zhm/timer.h
@@ -0,0 +1,56 @@
+/* This file is part of the Project Athena Zephyr Notification System.
+ * It contains definitions used by timer.c
+ *
+ * Created by: John T. Kohl
+ * Derived from timer_manager_.h by Ken Raeburn
+ *
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ */
+
+#ifndef __TIMER_H
+
+/*
+ * timer_manager_ -- routines for handling timers in login_shell
+ * (and elsewhere)
+ *
+ * Copyright 1986 Student Information Processing Board,
+ * Massachusetts Institute of Technology
+ *
+ * written by Ken Raeburn
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of M.I.T. and the Student
+Information Processing Board not be used in
+advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+M.I.T. and the Student Information Processing Board
+make no representations about the suitability of
+this software for any purpose. It is provided "as is"
+without express or implied warranty.
+
+ */
+
+typedef void (*timer_proc) __P((void *));
+
+typedef struct _Timer {
+ int heap_pos; /* Position in timer heap */
+ long abstime;
+ timer_proc func;
+ void *arg;
+} Timer;
+
+Timer *timer_set_rel __P((long, timer_proc, void *));
+Timer *timer_set_abs __P((long, timer_proc, void *));
+void timer_reset __P((Timer *));
+void timer_process __P((void));
+struct timeval *timer_timeout __P((struct timeval *tvbuf));
+
+#endif /* __TIMER_H */
+
diff --git a/zhm/zhm.c b/zhm/zhm.c
index ff89aec..51a67af 100644
--- a/zhm/zhm.c
+++ b/zhm/zhm.c
@@ -13,28 +13,9 @@
#include "zhm.h"
-static char rcsid_hm_c[] = "$Id$";
+static const char rcsid_hm_c[] = "$Id$";
-#ifdef POSIX
-#include <unistd.h>
-#include <stdlib.h>
-#endif
-
-#include <ctype.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-/*
- * warning: sys/param.h may include sys/types.h which may not be protected from
- * multiple inclusions on your system
- */
-#include <sys/param.h>
-
-#ifdef Z_HaveHesiod
-#include <hesiod.h>
+#ifdef ZEPHYR_USES_HESIOD
int use_hesiod = 0;
#endif
@@ -42,6 +23,12 @@ int use_hesiod = 0;
#define srandom srand48
#endif
+#ifdef _PATH_VARRUN
+#define PIDDIR _PATH_VARRUN
+#else
+#define PIDDIR "/etc/"
+#endif
+
int hmdebug, rebootflag, errflg, dieflag, inetd, oldpid, nofork;
int no_server = 1, nservchang, nserv, nclt;
int booting = 1, timeout_type, deactivated = 1;
@@ -49,219 +36,220 @@ long starttime;
u_short cli_port;
struct sockaddr_in cli_sin, serv_sin, from;
int numserv;
-char **serv_list = (char **)0;
+char **serv_list = NULL;
char prim_serv[MAXHOSTNAMELEN], cur_serv[MAXHOSTNAMELEN];
char *zcluster;
-int sig_type;
+int deactivating = 0;
+int terminating = 0;
struct hostent *hp;
char **clust_info;
char hostname[MAXHOSTNAMELEN], loopback[4];
-char *PidFile = PIDFILE;
-
-void choose_server(), init_hm(), detach(),
- handle_timeout(), resend_notices(), die_gracefully();
-
-#ifdef POSIX
-void
-#endif
- set_sig_type(sig)
- int sig;
+char PidFile[128];
+
+static RETSIGTYPE deactivate __P((void));
+static RETSIGTYPE terminate __P((void));
+static void choose_server __P((void));
+static void init_hm __P((void));
+static void detach __P((void));
+static void send_stats __P((ZNotice_t *, struct sockaddr_in *));
+static char *strsave __P((const char *));
+extern int optind;
+
+static RETSIGTYPE deactivate()
{
- sig_type = sig;
+ deactivating = 1;
}
-char *strsave();
+static RETSIGTYPE terminate()
+{
+ terminating = 1;
+}
main(argc, argv)
char *argv[];
{
- ZNotice_t notice;
- ZPacket_t packet;
- Code_t ret;
- int opt, pak_len;
- extern int optind;
- register int i, j = 0;
-
-#ifdef _AIX
- struct sigaction sa;
-
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_FULLDUMP;
- sa.sa_handler = SIG_DFL;
- sigaction(SIGSEGV, &sa, (struct sigaction *)0);
-#endif
-
- if (gethostname(hostname, MAXHOSTNAMELEN) < 0) {
- printf("Can't find my hostname?!\n");
- exit(-1);
- }
- prim_serv[0] = '\0';
- while ((opt = getopt(argc, argv, "drhin")) != EOF)
- switch(opt) {
+ ZNotice_t notice;
+ ZPacket_t packet;
+ Code_t ret;
+ int opt, pak_len, i, j = 0, fd, count;
+ fd_set readers;
+ struct timeval tv;
+
+ sprintf(PidFile, "%szhm.pid", PIDDIR);
+
+ if (gethostname(hostname, MAXHOSTNAMELEN) < 0) {
+ printf("Can't find my hostname?!\n");
+ exit(-1);
+ }
+ prim_serv[0] = '\0';
+ while ((opt = getopt(argc, argv, "drhin")) != EOF)
+ switch(opt) {
case 'd':
- hmdebug++;
- break;
+ hmdebug = 1;
+ break;
case 'h':
- /* Die on SIGHUP */
- dieflag++;
- break;
+ /* Die on SIGHUP */
+ dieflag = 1;
+ break;
case 'r':
- /* Reboot host -- send boot notice -- and exit */
- rebootflag++;
- break;
+ /* Reboot host -- send boot notice -- and exit */
+ rebootflag= 1;
+ break;
case 'i':
- /* inetd operation: don't do bind ourselves, fd 0 is
- already connected to a socket. Implies -h */
- inetd++;
- dieflag++;
- break;
+ /* inetd operation: don't do bind ourselves, fd 0 is
+ already connected to a socket. Implies -h */
+ inetd = 1;
+ dieflag = 1;
+ break;
case 'n':
- nofork = 1;
- break;
+ nofork = 1;
+ break;
case '?':
default:
- errflg++;
- break;
- }
- if (errflg) {
- fprintf(stderr, "Usage: %s [-d] [-h] [-r] [-n] [server]\n", argv[0]);
- exit(2);
- }
+ errflg++;
+ break;
+ }
+ if (errflg) {
+ fprintf(stderr, "Usage: %s [-d] [-h] [-r] [-n] [server]\n", argv[0]);
+ exit(2);
+ }
+
+ numserv = 0;
- numserv = 0;
-
- /* Override server argument? */
- if (optind < argc) {
- if ((hp = gethostbyname(argv[optind++])) == NULL) {
- printf("Unknown server name: %s\n", argv[optind-1]);
- } else
- (void) strcpy(prim_serv, hp->h_name);
-
- /* argc-optind is the # of other servers on the command line */
- serv_list = (char **)malloc((argc-optind + 2) * sizeof(char *));
- serv_list[numserv++] = prim_serv;
- for (; optind < argc; optind++) {
- if ((hp = gethostbyname(argv[optind])) == NULL) {
- printf("Unknown server name '%s', ignoring\n", argv[optind]);
- continue;
- }
+ /* Override server argument? */
+ if (optind < argc) {
+ if ((hp = gethostbyname(argv[optind++])) == NULL) {
+ printf("Unknown server name: %s\n", argv[optind-1]);
+ } else
+ strcpy(prim_serv, hp->h_name);
+
+ /* argc-optind is the # of other servers on the command line */
+ serv_list = (char **) malloc((argc - optind + 2) * sizeof(char *));
+ serv_list[numserv++] = prim_serv;
+ for (; optind < argc; optind++) {
+ if ((hp = gethostbyname(argv[optind])) == NULL) {
+ printf("Unknown server name '%s', ignoring\n", argv[optind]);
+ continue;
+ }
serv_list[numserv++] = strsave(hp->h_name);
- }
- serv_list[numserv] = NULL;
- }
-#ifdef Z_HaveHesiod
- else
- use_hesiod = 1;
+ }
+ serv_list[numserv] = NULL;
+ }
+#ifdef ZEPHYR_USES_HESIOD
+ else
+ use_hesiod = 1;
#endif
- choose_server();
- if (*prim_serv == '\0') {
- printf("No valid primary server found, exiting.\n");
- exit(ZERR_SERVNAK);
- }
- init_hm();
+ choose_server();
+ if (*prim_serv == '\0') {
+ printf("No valid primary server found, exiting.\n");
+ exit(ZERR_SERVNAK);
+ }
+ init_hm();
- DPR2 ("zephyr server port: %u\n", ntohs(serv_sin.sin_port));
- DPR2 ("zephyr client port: %u\n", ntohs(cli_port));
+ DPR2("zephyr server port: %u\n", ntohs(serv_sin.sin_port));
+ DPR2("zephyr client port: %u\n", ntohs(cli_port));
- /* Main loop */
- for ever {
- DPR ("Waiting for a packet...");
- switch(sig_type) {
- case 0:
- break;
- case SIGHUP: /* A SIGHUP means we are deactivating the ws. */
- sig_type = 0;
- if (dieflag) {
- die_gracefully();
- } else {
- choose_server();
- send_flush_notice(HM_FLUSH);
- deactivated = 1;
- }
- break;
- case SIGTERM:
- sig_type = 0;
- die_gracefully();
- break;
- case SIGALRM:
- sig_type = 0;
- handle_timeout();
- break;
- default:
- sig_type = 0;
- syslog (LOG_WARNING, "Unknown system interrupt.");
- break;
- }
- ret = ZReceivePacket(packet, &pak_len, &from);
- if ((ret != ZERR_NONE) && (ret != EINTR)){
- Zperr(ret);
- com_err("hm", ret, "receiving notice");
- } else if (ret != EINTR) {
- /* Where did it come from? */
- if ((ret = ZParseNotice(packet, pak_len, &notice))
- != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "parsing notice");
- } else {
- DPR ("Got a packet.\n");
- DPR ("notice:\n");
- DPR2("\tz_kind: %d\n", notice.z_kind);
- DPR2("\tz_port: %u\n", ntohs(notice.z_port));
- DPR2("\tz_class: %s\n", notice.z_class);
- DPR2("\tz_class_inst: %s\n", notice.z_class_inst);
- DPR2("\tz_opcode: %s\n", notice.z_opcode);
- DPR2("\tz_sender: %s\n", notice.z_sender);
- DPR2("\tz_recip: %s\n", notice.z_recipient);
- DPR2("\tz_def_format: %s\n", notice.z_default_format);
- DPR2("\tz_message: %s\n", notice.z_message);
- if (memcmp(loopback, (char *)&from.sin_addr, 4) &&
- ((notice.z_kind == SERVACK) ||
- (notice.z_kind == SERVNAK) ||
- (notice.z_kind == HMCTL))) {
- server_manager(&notice);
- } else {
- if (!memcmp(loopback, (char *)&from.sin_addr, 4) &&
- ((notice.z_kind == UNSAFE) ||
- (notice.z_kind == UNACKED) ||
- (notice.z_kind == ACKED) ||
- (notice.z_kind == HMCTL))) {
- /* Client program... */
- if (deactivated) {
+ /* Main loop */
+ for ever {
+ /* Wait for incoming packets or queue timeouts. */
+ DPR("Waiting for a packet...");
+ fd = ZGetFD();
+ FD_ZERO(&readers);
+ FD_SET(fd, &readers);
+ count = select(fd + 1, &readers, NULL, NULL, timer_timeout(&tv));
+ if (count == -1 && errno != EINTR) {
+ syslog(LOG_CRIT, "select() failed: %m");
+ die_gracefully();
+ }
+
+ if (terminating)
+ die_gracefully();
+
+ if (deactivating) {
+ deactivating = 0;
+ if (dieflag) {
+ die_gracefully();
+ } else {
+ choose_server();
+ send_flush_notice(HM_FLUSH);
+ deactivated = 1;
+ }
+ }
+
+ timer_process();
+
+ if (count > 0) {
+ ret = ZReceivePacket(packet, &pak_len, &from);
+ if ((ret != ZERR_NONE) && (ret != EINTR)){
+ Zperr(ret);
+ com_err("hm", ret, "receiving notice");
+ } else if (ret != EINTR) {
+ /* Where did it come from? */
+ if ((ret = ZParseNotice(packet, pak_len, &notice))
+ != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "parsing notice");
+ } else {
+ DPR("Got a packet.\n");
+ DPR("notice:\n");
+ DPR2("\tz_kind: %d\n", notice.z_kind);
+ DPR2("\tz_port: %u\n", ntohs(notice.z_port));
+ DPR2("\tz_class: %s\n", notice.z_class);
+ DPR2("\tz_class_inst: %s\n", notice.z_class_inst);
+ DPR2("\tz_opcode: %s\n", notice.z_opcode);
+ DPR2("\tz_sender: %s\n", notice.z_sender);
+ DPR2("\tz_recip: %s\n", notice.z_recipient);
+ DPR2("\tz_def_format: %s\n", notice.z_default_format);
+ DPR2("\tz_message: %s\n", notice.z_message);
+ if (memcmp(loopback, &from.sin_addr, 4) &&
+ ((notice.z_kind == SERVACK) ||
+ (notice.z_kind == SERVNAK) ||
+ (notice.z_kind == HMCTL))) {
+ server_manager(&notice);
+ } else {
+ if (!memcmp(loopback, &from.sin_addr, 4) &&
+ ((notice.z_kind == UNSAFE) ||
+ (notice.z_kind == UNACKED) ||
+ (notice.z_kind == ACKED) ||
+ (notice.z_kind == HMCTL))) {
+ /* Client program... */
+ if (deactivated) {
send_boot_notice(HM_BOOT);
deactivated = 0;
- }
- transmission_tower(&notice, packet, pak_len);
- DPR2 ("Pending = %d\n", ZPending());
- } else {
- if (notice.z_kind == STAT) {
+ }
+ transmission_tower(&notice, packet, pak_len);
+ DPR2("Pending = %d\n", ZPending());
+ } else {
+ if (notice.z_kind == STAT) {
send_stats(&notice, &from);
- } else {
+ } else {
syslog(LOG_INFO,
"Unknown notice type: %d",
notice.z_kind);
- }
- }
- }
- }
- }
- }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
-void choose_server()
+static void choose_server()
{
int i = 0;
-#ifdef Z_HaveHesiod
+#ifdef ZEPHYR_USES_HESIOD
if (use_hesiod) {
/* Free up any previously used resources */
if (prim_serv[0])
i = 1;
while (i < numserv)
- (void) free(serv_list[i++]);
+ free(serv_list[i++]);
if (serv_list)
- (void) free(serv_list);
+ free(serv_list);
numserv = 0;
prim_serv[0] = '\0';
@@ -280,7 +268,7 @@ void choose_server()
if ((c = strchr(*clust_info, ' ')) == 0) {
printf("Hesiod error getting primary server info.\n");
} else
- (void)strcpy(prim_serv, c+1);
+ strcpy(prim_serv, c+1);
break;
}
if (!strncasecmp("ZCLUSTER", *clust_info, 9)) {
@@ -291,7 +279,7 @@ void choose_server()
} else {
if ((zcluster = malloc((unsigned)(strlen(c+1)+1)))
!= NULL) {
- (void)strcpy(zcluster, c+1);
+ strcpy(zcluster, c+1);
} else {
printf("Out of memory.\n");
exit(-5);
@@ -303,14 +291,14 @@ void choose_server()
if (zcluster == NULL) {
if ((zcluster = malloc((unsigned)(strlen("zephyr")+1))) != NULL)
- (void)strcpy(zcluster, "zephyr");
+ strcpy(zcluster, "zephyr");
}
while ((serv_list = hes_resolve(zcluster, "sloc")) == (char **)NULL) {
syslog(LOG_ERR, "No servers or no hesiod");
/* wait a bit, and try again */
sleep(30);
}
- clust_info = (char **)malloc(2*sizeof(char *));
+ clust_info = (char **) malloc(2 * sizeof(char *));
if (prim_serv[0])
clust_info[numserv++] = prim_serv;
for (i = 0; serv_list[i]; i++)
@@ -327,85 +315,68 @@ void choose_server()
#endif
if (!prim_serv[0] && numserv) {
- srandom(time((long *) 0));
- (void) strcpy(prim_serv, serv_list[random() % numserv]);
+ srandom(time(NULL));
+ strcpy(prim_serv, serv_list[random() % numserv]);
}
}
-void init_hm()
+static void init_hm()
{
struct servent *sp;
Code_t ret;
FILE *fp;
-#ifdef POSIX
+#ifdef _POSIX_VERSION
struct sigaction sa;
#endif
starttime = time((time_t *)0);
OPENLOG("hm", LOG_PID, LOG_DAEMON);
+ ZSetServerState(1); /* Aargh!!! */
if ((ret = ZInitialize()) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "initializing");
- closelog();
- exit(-1);
+ Zperr(ret);
+ com_err("hm", ret, "initializing");
+ closelog();
+ exit(-1);
}
- (void)ZSetServerState(1); /* Aargh!!! */
init_queue();
if (*prim_serv == '\0')
- (void)strcpy(prim_serv, *serv_list);
+ strcpy(prim_serv, *serv_list);
loopback[0] = 127;
loopback[1] = 0;
loopback[2] = 0;
loopback[3] = 1;
- /* kill old hm if it exists */
- fp = fopen(PidFile, "r");
- if (fp != NULL) {
- (void)fscanf(fp, "%d\n", &oldpid);
- while (!kill(oldpid, SIGTERM))
- sleep(1);
- syslog(LOG_INFO, "Killed old image.");
- (void) fclose(fp);
- }
-
if (inetd) {
- (void) ZSetFD(0); /* fd 0 is on the socket,
- thanks to inetd */
+ ZSetFD(0); /* fd 0 is on the socket, thanks to inetd */
} else {
- /* Open client socket, for receiving client and server notices */
- if ((sp = getservbyname(HM_SVCNAME, "udp")) == NULL) {
- printf("No %s entry in /etc/services.\n", HM_SVCNAME);
- exit(1);
- }
- cli_port = sp->s_port;
+ /* Open client socket, for receiving client and server notices */
+ sp = getservbyname(HM_SVCNAME, "udp");
+ cli_port = (sp) ? sp->s_port : HM_SVC_FALLBACK;
- if ((ret = ZOpenPort(&cli_port)) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "opening port");
- exit(ret);
- }
+ if ((ret = ZOpenPort(&cli_port)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "opening port");
+ exit(ret);
+ }
}
cli_sin = ZGetDestAddr();
-
- /* Open the server socket */
-
- if ((sp = getservbyname(SERVER_SVCNAME, "udp")) == NULL) {
- printf("No %s entry in /etc/services.\n", SERVER_SVCNAME);
- exit(1);
- }
+ sp = getservbyname(SERVER_SVCNAME, "udp");
+ memset(&serv_sin, 0, sizeof(struct sockaddr_in));
+ serv_sin.sin_port = (sp) ? sp->s_port : SERVER_SVC_FALLBACK;
+
#ifndef DEBUG
if (!inetd && !nofork)
- detach();
+ detach();
/* Write pid to file */
fp = fopen(PidFile, "w");
if (fp != NULL) {
- fprintf(fp, "%d\n", getpid());
- (void) fclose(fp);
+ fprintf(fp, "%d\n", getpid());
+ fclose(fp);
}
#endif /* DEBUG */
@@ -413,9 +384,6 @@ void init_hm()
syslog(LOG_INFO, "Debugging on.");
}
- (void) memset((char *)&serv_sin, 0, sizeof(struct sockaddr_in));
- serv_sin.sin_port = sp->s_port;
-
/* Set up communications with server */
/* target is SERVER_SVCNAME port on server machine */
@@ -424,31 +392,30 @@ void init_hm()
/* who to talk to */
if ((hp = gethostbyname(prim_serv)) == NULL) {
DPR("gethostbyname failed\n");
- find_next_server((char *)NULL);
+ find_next_server(NULL);
} else {
- DPR2 ("Server = %s\n", prim_serv);
- (void)strcpy(cur_serv, prim_serv);
- (void)memcpy((char *)&serv_sin.sin_addr, hp->h_addr, hp->h_length);
+ DPR2("Server = %s\n", prim_serv);
+ strcpy(cur_serv, prim_serv);
+ memcpy(&serv_sin.sin_addr, hp->h_addr, hp->h_length);
}
send_boot_notice(HM_BOOT);
deactivated = 0;
-#ifdef POSIX
+#ifdef _POSIX_VERSION
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
- sa.sa_handler = set_sig_type;
+ sa.sa_handler = deactivate;
sigaction(SIGHUP, &sa, (struct sigaction *)0);
- sigaction(SIGALRM, &sa, (struct sigaction *)0);
+ sa.sa_handler = terminate;
sigaction(SIGTERM, &sa, (struct sigaction *)0);
#else
- (void)signal (SIGHUP, set_sig_type);
- (void)signal (SIGALRM, set_sig_type);
- (void)signal (SIGTERM, set_sig_type);
+ signal(SIGHUP, deactivate);
+ signal(SIGTERM, terminate);
#endif
}
-void detach()
+static void detach()
{
/* detach from terminal and fork. */
register int i, x = ZGetFD();
@@ -459,31 +426,36 @@ void detach()
perror("fork");
exit(0);
}
-#ifdef POSIX
+#ifdef _POSIX_VERSION
size = sysconf(_SC_OPEN_MAX);
#else
size = getdtablesize();
#endif
for (i = 0; i < size; i++)
if (i != x)
- (void) close(i);
+ close(i);
- if ((i = open("/dev/tty", O_RDWR, 666)) < 0)
+ if ((i = open("/dev/tty", O_RDWR, 0666)) < 0)
; /* Can't open tty, but don't flame about it. */
else {
#ifdef TIOCNOTTY
- (void) ioctl(i, TIOCNOTTY, (caddr_t) 0);
+ /* Necessary for old non-POSIX systems which automatically assign
+ * an opened tty as the controlling terminal of a process which
+ * doesn't already have one. POSIX systems won't include
+ * <sys/ioctl.h> (see ../h/sysdep.h); if TIOCNOTTY is defined anyway,
+ * this is unnecessary but won't hurt. */
+ ioctl(i, TIOCNOTTY, (caddr_t) 0);
#endif
- (void) close(i);
+ close(i);
}
-#ifdef POSIX
- (void) setsid();
+#ifdef _POSIX_VERSION
+ setsid();
#endif
}
static char version[BUFSIZ];
-send_stats(notice, sin)
+static void send_stats(notice, sin)
ZNotice_t *notice;
struct sockaddr_in *sin;
{
@@ -492,7 +464,7 @@ send_stats(notice, sin)
char *bfr;
char *list[20];
int len, i, nitems = 10;
- unsigned int size;
+ unsigned long size;
newnotice = *notice;
@@ -502,91 +474,75 @@ send_stats(notice, sin)
}
newnotice.z_kind = HMACK;
- list[0] = (char *)malloc(MAXHOSTNAMELEN);
- (void)strcpy(list[0], cur_serv);
- list[1] = (char *)malloc(64);
- (void)sprintf(list[1], "%d", queue_len());
- list[2] = (char *)malloc(64);
- (void)sprintf(list[2], "%d", nclt);
- list[3] = (char *)malloc(64);
- (void)sprintf(list[3], "%d", nserv);
- list[4] = (char *)malloc(64);
- (void)sprintf(list[4], "%d", nservchang);
- list[5] = (char *)malloc(64);
- (void)strcpy(list[5], rcsid_hm_c);
- list[6] = (char *)malloc(64);
+ list[0] = (char *) malloc(MAXHOSTNAMELEN);
+ strcpy(list[0], cur_serv);
+ list[1] = (char *) malloc(64);
+ sprintf(list[1], "%d", queue_len());
+ list[2] = (char *) malloc(64);
+ sprintf(list[2], "%d", nclt);
+ list[3] = (char *) malloc(64);
+ sprintf(list[3], "%d", nserv);
+ list[4] = (char *) malloc(64);
+ sprintf(list[4], "%d", nservchang);
+ list[5] = (char *) malloc(64);
+ strcpy(list[5], rcsid_hm_c);
+ list[6] = (char *) malloc(64);
if (no_server)
- (void)sprintf(list[6], "yes");
+ sprintf(list[6], "yes");
else
- (void)sprintf(list[6], "no");
- list[7] = (char *)malloc(64);
- (void)sprintf(list[7], "%ld", time((time_t *)0) - starttime);
+ sprintf(list[6], "no");
+ list[7] = (char *) malloc(64);
+ sprintf(list[7], "%ld", time((time_t *)0) - starttime);
#ifdef adjust_size
- size = (unsigned int)sbrk(0);
+ size = (unsigned long)sbrk(0);
adjust_size (size);
#else
size = -1;
#endif
list[8] = (char *)malloc(64);
- (void)sprintf(list[8], "%ld", size);
+ sprintf(list[8], "%ld", size);
list[9] = (char *)malloc(32);
- (void)strcpy(list[9], MACHINE);
+ strcpy(list[9], MACHINE_TYPE);
/* Since ZFormatRaw* won't change the version number on notices,
we need to set the version number explicitly. This code is taken
from Zinternal.c, function Z_FormatHeader */
if (!*version)
- (void) sprintf(version, "%s%d.%d", ZVERSIONHDR, ZVERSIONMAJOR,
- ZVERSIONMINOR);
+ sprintf(version, "%s%d.%d", ZVERSIONHDR, ZVERSIONMAJOR,
+ ZVERSIONMINOR);
newnotice.z_version = version;
if ((ret = ZFormatRawNoticeList(&newnotice, list, nitems, &bfr,
&len)) != ZERR_NONE) {
- syslog(LOG_INFO, "Couldn't format stats packet");
- } else
- if ((ret = ZSendPacket(bfr, len, 0)) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "sending stats");
- }
+ syslog(LOG_INFO, "Couldn't format stats packet");
+ } else {
+ if ((ret = ZSendPacket(bfr, len, 0)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "sending stats");
+ }
+ }
free(bfr);
for(i=0;i<nitems;i++)
free(list[i]);
}
-void handle_timeout()
-{
- switch(timeout_type) {
- case BOOTING:
- new_server((char *)NULL);
- break;
- case NOTICES:
- DPR ("Notice timeout\n");
- resend_notices(&serv_sin);
- break;
- default:
- syslog (LOG_ERR, "Unknown timeout type: %d\n", timeout_type);
- break;
- }
-}
-
void die_gracefully()
{
syslog(LOG_INFO, "Terminate signal caught...");
send_flush_notice(HM_FLUSH);
- (void)unlink(PidFile);
+ unlink(PidFile);
closelog();
exit(0);
}
-char *
-strsave(sp)
-char *sp;
+static char *strsave(sp)
+ const char *sp;
{
register char *ret;
if((ret = malloc((unsigned) strlen(sp)+1)) == NULL) {
abort();
}
- (void) strcpy(ret,sp);
+ strcpy(ret,sp);
return(ret);
}
diff --git a/zhm/zhm.h b/zhm/zhm.h
index 4b7293d..0e0f5b8 100644
--- a/zhm/zhm.h
+++ b/zhm/zhm.h
@@ -15,14 +15,23 @@
*/
#include <zephyr/mit-copyright.h>
-#include <zephyr/zephyr.h>
-#include <zephyr/zsyslog.h>
+#include <internal.h>
#include <sys/socket.h>
-#include <sys/param.h>
-#include <netdb.h>
-#ifdef lint
-#include <sys/uio.h> /* make lint shut up */
-#endif /* lint */
+#include <sys/time.h>
+#include "timer.h"
+
+/* These macros are for insertion into and deletion from a singly-linked list
+ * with back pointers to the previous element's next pointer. In order to
+ * make these macros act like expressions, they use the comma operator for
+ * sequenced evaluations of assignment, and "a && b" for "evaluate assignment
+ * b if expression a is true". */
+#define LIST_INSERT(head, elem) \
+ ((elem)->next = *(head), \
+ (*head) && ((*(head))->prev_p = &(elem)->next), \
+ (*head) = (elem), (elem)->prev_p = (head))
+#define LIST_DELETE(elem) \
+ (*(elem)->prev_p = (elem)->next, \
+ (elem)->next && ((elem)->next->prev_p = (elem)->prev_p))
#ifdef DEBUG
#define DPR(a) fprintf(stderr, a); fflush(stderr)
@@ -36,76 +45,58 @@
#define ever (;;)
-#define SERV_TIMEOUT 20
+#define SERV_TIMEOUT 5
#define BOOTING 1
#define NOTICES 2
-extern Code_t send_outgoing();
-extern void init_queue(), retransmit_queue();
+/* main.c */
+void die_gracefully __P((void));
+
+/* zhm_client.c */
+void transmission_tower __P((ZNotice_t *, char *, int));
+Code_t send_outgoing __P((ZNotice_t *));
+
+/* queue.c */
+void init_queue __P((void));
+Code_t add_notice_to_queue __P((ZNotice_t *, char *, struct sockaddr_in *,
+ int));
+Code_t remove_notice_from_queue __P((ZNotice_t *, ZNotice_Kind_t *,
+ struct sockaddr_in *));
+void retransmit_queue __P((struct sockaddr_in *));
+void disable_queue_retransmits __P((void));
+int queue_len __P((void));
+
+struct sockaddr_in serv_sin;
extern int rexmit_times[];
#ifdef vax
-#define MACHINE "vax"
#define use_etext
-#define ok
#endif /* vax */
#ifdef ibm032
-#define MACHINE "rt"
#define adjust_size(size) size -= 0x10000000
-#define ok
#endif /* ibm032 */
-#ifdef NeXT
-#define MACHINE "NeXT"
-#define ok
-#endif /* NeXT */
-
-#ifdef sun
-#ifdef SUN2_ARCH
-#define MACHINE "sun2"
-#define ok
-#endif /* SUN2_ARCH */
-
-#ifdef SUN3_ARCH
-#define MACHINE "sun3"
-#define ok
-#endif /* SUN3_ARCH */
-
-#if defined (SUN4_ARCH) || defined (sparc)
-#define MACHINE "sun4"
+#if defined(sun) && (defined (SUN4_ARCH) || defined (sparc))
#define use_etext
-#define ok
-#endif /* SUN4_ARCH */
-
-#ifndef ok
-#if defined (m68k)
-#define MACHINE "sun (unknown 68k)"
-#else
-#define MACHINE "sun (unknown)"
#endif
-#define ok
-#endif /* ! ok */
-#endif /* sun */
#ifdef _AIX
#ifdef i386
-#define MACHINE "ps2"
#define adjust_size(size) size -= 0x400000
#endif
#ifdef _IBMR2
-#define MACHINE "IBM RISC/6000"
#define adjust_size(size) size -= 0x20000000
#endif
-#define ok
#endif
-#if defined(ultrix) && defined(mips)
-#define MACHINE "decmips"
+#if (defined(ultrix) || defined(sgi)) && defined(mips)
#define adjust_size(size) size -= 0x10000000
-#define ok
-#endif /* ultrix && mips */
+#endif /* (ultrix || sgi) && mips */
+#if defined(__alpha)
+#define adjust_size(size) size -= 0x140000000
+#endif /* alpha */
#ifdef use_etext
extern int etext;
@@ -113,9 +104,4 @@ extern int etext;
#undef use_etext
#endif
-#ifndef ok
-#define MACHINE "unknown"
-#endif
-#undef ok
-
#endif
diff --git a/zhm/zhm_client.c b/zhm/zhm_client.c
index ec41466..ff7d3ea 100644
--- a/zhm/zhm_client.c
+++ b/zhm/zhm_client.c
@@ -19,89 +19,84 @@ static char rcsid_hm_client_c[] = "$Header$";
#endif /* SABER */
#endif /* lint */
-extern int no_server, timeout_type, nclt, deactivated;
+extern int no_server, nclt, deactivated;
extern struct sockaddr_in cli_sin, serv_sin, from;
-transmission_tower(notice, packet, pak_len)
+void transmission_tower(notice, packet, pak_len)
ZNotice_t *notice;
- caddr_t packet;
+ char *packet;
int pak_len;
{
- ZNotice_t gack;
- Code_t ret;
- struct sockaddr_in gsin;
- unsigned int tleft;
+ ZNotice_t gack;
+ Code_t ret;
+ struct sockaddr_in gsin;
- nclt++;
- if (notice->z_kind == HMCTL) {
- if (!strcmp(notice->z_opcode, CLIENT_FLUSH)) {
- send_flush_notice(HM_FLUSH);
- deactivated = 1;
- }
- else if (!strcmp(notice->z_opcode, CLIENT_NEW_SERVER))
- new_server((char *)NULL);
- else
- syslog (LOG_INFO, "Bad control notice from client.");
- return;
- } else
+ nclt++;
+ if (notice->z_kind == HMCTL) {
+ if (!strcmp(notice->z_opcode, CLIENT_FLUSH)) {
+ send_flush_notice(HM_FLUSH);
+ deactivated = 1;
+ } else if (!strcmp(notice->z_opcode, CLIENT_NEW_SERVER)) {
+ new_server((char *)NULL);
+ } else {
+ syslog (LOG_INFO, "Bad control notice from client.");
+ }
+ return;
+ } else {
if (notice->z_kind != UNSAFE) {
- gack = *notice;
- gack.z_kind = HMACK;
- gack.z_message_len = 0;
- gack.z_multinotice = "";
- gsin = cli_sin;
- gsin.sin_port = from.sin_port;
- if (gack.z_port == 0)
+ gack = *notice;
+ gack.z_kind = HMACK;
+ gack.z_message_len = 0;
+ gack.z_multinotice = "";
+ gsin = cli_sin;
+ gsin.sin_port = from.sin_port;
+ if (gack.z_port == 0)
gack.z_port = from.sin_port;
- DPR2 ("Client Port = %u\n", ntohs(gack.z_port));
- notice->z_port = gack.z_port;
- if ((ret = ZSetDestAddr(&gsin)) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "setting destination");
- }
- /* Bounce ACK to library */
- if ((ret = send_outgoing(&gack)) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "sending raw notice");
- }
- }
- if (!no_server) {
- DPR2 ("Server Port = %u\n", ntohs(serv_sin.sin_port));
- if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "setting destination");
+ DPR2 ("Client Port = %u\n", ntohs(gack.z_port));
+ notice->z_port = gack.z_port;
+ if ((ret = ZSetDestAddr(&gsin)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "setting destination");
}
- if ((ret = send_outgoing(notice)) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "while sending raw notice");
+ /* Bounce ACK to library */
+ if ((ret = send_outgoing(&gack)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "sending raw notice");
}
- if (tleft = alarm(0))
- (void)alarm(tleft);
- else {
- timeout_type = NOTICES;
- (void)alarm(rexmit_times[0]);
- }
- }
- (void)add_notice_to_queue(notice, packet, &gsin, pak_len);
+ }
+ }
+ if (!no_server) {
+ DPR2 ("Server Port = %u\n", ntohs(serv_sin.sin_port));
+ if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "setting destination");
+ }
+ if ((ret = send_outgoing(notice)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "while sending raw notice");
+ }
+ }
+ add_notice_to_queue(notice, packet, &gsin, pak_len);
}
Code_t
send_outgoing(notice)
ZNotice_t *notice;
{
- Code_t retval;
- char *packet;
- int length;
+ Code_t retval;
+ char *packet;
+ int length;
- if (!(packet = (char *) malloc((unsigned)sizeof(ZPacket_t))))
- return(ENOMEM);
+ if (!(packet = (char *) malloc((unsigned)sizeof(ZPacket_t))))
+ return(ENOMEM);
- if ((retval = ZFormatSmallRawNotice(notice, packet, &length))
- != ZERR_NONE) {
- free(packet);
- return(retval);
- }
- retval = ZSendPacket(packet, length, 0);
+ if ((retval = ZFormatSmallRawNotice(notice, packet, &length))
+ != ZERR_NONE) {
free(packet);
return(retval);
+ }
+ retval = ZSendPacket(packet, length, 0);
+ free(packet);
+ return(retval);
}
+
diff --git a/zhm/zhm_server.c b/zhm/zhm_server.c
index 8d95788..760d4c7 100644
--- a/zhm/zhm_server.c
+++ b/zhm/zhm_server.c
@@ -19,6 +19,10 @@ static char rcsid_hm_server_c[] = "$Header$";
#endif /* SABER */
#endif /* lint */
+static void boot_timeout __P((void *));
+
+static Timer *boot_timer = NULL;
+
int serv_loop = 0;
extern u_short cli_port;
extern struct sockaddr_in serv_sin, from;
@@ -59,8 +63,7 @@ char *op;
Zperr(ret);
com_err("hm", ret, "sending startup notice");
}
- timeout_type = BOOTING;
- (void)alarm(SERV_TIMEOUT);
+ boot_timer = timer_set_rel(SERV_TIMEOUT, boot_timeout, NULL);
}
/* Argument is whether we are detaching or really going down */
@@ -165,121 +168,130 @@ char *sugg_serv;
server_manager(notice)
ZNotice_t *notice;
{
- if (memcmp((char *)&serv_sin.sin_addr, (char *)&from.sin_addr, 4) ||
- (serv_sin.sin_port != from.sin_port)) {
- syslog (LOG_INFO, "Bad notice from port %u.", notice->z_port);
- } else {
- /* This is our server, handle the notice */
- booting = 0;
- DPR ("A notice came in from the server.\n");
- nserv++;
- switch(notice->z_kind) {
- case HMCTL:
- hm_control(notice);
- break;
- case SERVNAK:
- case SERVACK:
- send_back(notice);
- break;
- default:
- syslog (LOG_INFO, "Bad notice kind!?");
- break;
- }
- }
+ if (memcmp((char *)&serv_sin.sin_addr, (char *)&from.sin_addr, 4) ||
+ (serv_sin.sin_port != from.sin_port)) {
+ syslog (LOG_INFO, "Bad notice from port %u.", notice->z_port);
+ } else {
+ /* This is our server, handle the notice */
+ if (boot_timer) {
+ timer_reset(boot_timer);
+ boot_timer = NULL;
+ }
+ DPR ("A notice came in from the server.\n");
+ nserv++;
+ switch(notice->z_kind) {
+ case HMCTL:
+ hm_control(notice);
+ break;
+ case SERVNAK:
+ case SERVACK:
+ send_back(notice);
+ break;
+ default:
+ syslog (LOG_INFO, "Bad notice kind!?");
+ break;
+ }
+ }
}
hm_control(notice)
ZNotice_t *notice;
{
- Code_t ret;
- struct hostent *hp;
- char suggested_server[64];
- unsigned long addr;
+ Code_t ret;
+ struct hostent *hp;
+ char suggested_server[64];
+ unsigned long addr;
- DPR("Control message!\n");
- if (!strcmp(notice->z_opcode, SERVER_SHUTDOWN)) {
- if (notice->z_message_len) {
- addr = inet_addr(notice->z_message);
- if ((hp = gethostbyaddr((char *)&addr, sizeof(addr),
- AF_INET)) != NULL) {
- (void)strcpy(suggested_server, hp->h_name);
- new_server(suggested_server);
- } else
- new_server((char *)NULL);
- }
- else
- new_server((char *)NULL);
- } else if (!strcmp(notice->z_opcode, SERVER_PING)) {
- if (no_server)
- (void)alarm(0);
- notice->z_kind = HMACK;
- if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "setting destination");
- }
- if ((ret = send_outgoing(notice)) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "sending ACK");
- }
- if (no_server) {
- no_server = 0;
- retransmit_queue(&serv_sin);
- }
- } else
- syslog (LOG_INFO, "Bad control message.");
+ DPR("Control message!\n");
+ if (!strcmp(notice->z_opcode, SERVER_SHUTDOWN)) {
+ if (notice->z_message_len) {
+ addr = inet_addr(notice->z_message);
+ hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
+ if (hp != NULL) {
+ strcpy(suggested_server, hp->h_name);
+ new_server(suggested_server);
+ } else {
+ new_server(NULL);
+ }
+ } else {
+ new_server((char *)NULL);
+ }
+ } else if (!strcmp(notice->z_opcode, SERVER_PING)) {
+ notice->z_kind = HMACK;
+ if ((ret = ZSetDestAddr(&serv_sin)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "setting destination");
+ }
+ if ((ret = send_outgoing(notice)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "sending ACK");
+ }
+ if (no_server) {
+ no_server = 0;
+ retransmit_queue(&serv_sin);
+ }
+ } else {
+ syslog (LOG_INFO, "Bad control message.");
+ }
}
send_back(notice)
ZNotice_t *notice;
{
- ZNotice_Kind_t kind;
- struct sockaddr_in repl;
- Code_t ret;
+ ZNotice_Kind_t kind;
+ struct sockaddr_in repl;
+ Code_t ret;
- if (no_server)
- (void)alarm(0);
- if (!strcmp(notice->z_opcode, HM_BOOT) ||
- !strcmp(notice->z_opcode, HM_ATTACH)) {
- /* ignore message, just an ack from boot, but exit if we
- * are rebooting.
- */
- if (rebootflag)
- die_gracefully();
- } else {
- if (remove_notice_from_queue(notice, &kind,
- &repl) != ZERR_NONE) {
- syslog (LOG_INFO, "Hey! This packet isn't in my queue!");
- } else {
- /* check if client wants an ACK, and send it */
- if (kind == ACKED) {
- DPR2 ("Client ACK port: %u\n", ntohs(repl.sin_port));
- if ((ret = ZSetDestAddr(&repl)) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "setting destination");
- }
- if ((ret = send_outgoing(notice)) != ZERR_NONE) {
- Zperr(ret);
- com_err("hm", ret, "sending ACK");
- }
- }
- }
- }
- if (no_server) {
- no_server = 0;
- retransmit_queue(&serv_sin);
- }
+ if (!strcmp(notice->z_opcode, HM_BOOT) ||
+ !strcmp(notice->z_opcode, HM_ATTACH)) {
+ /* ignore message, just an ack from boot, but exit if we
+ * are rebooting.
+ */
+ if (rebootflag)
+ die_gracefully();
+ } else {
+ if (remove_notice_from_queue(notice, &kind, &repl) != ZERR_NONE) {
+ syslog (LOG_INFO, "Hey! This packet isn't in my queue!");
+ } else {
+ /* check if client wants an ACK, and send it */
+ if (kind == ACKED) {
+ DPR2 ("Client ACK port: %u\n", ntohs(repl.sin_port));
+ if ((ret = ZSetDestAddr(&repl)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "setting destination");
+ }
+ if ((ret = send_outgoing(notice)) != ZERR_NONE) {
+ Zperr(ret);
+ com_err("hm", ret, "sending ACK");
+ }
+ }
+ }
+ }
+ if (no_server) {
+ no_server = 0;
+ retransmit_queue(&serv_sin);
+ }
}
new_server(sugg_serv)
char *sugg_serv;
{
- no_server = 1;
- syslog (LOG_INFO, "Server went down, finding new server.");
- send_flush_notice(HM_DETACH);
- find_next_server(sugg_serv);
- if (booting) {
- send_boot_notice(HM_BOOT);
- deactivated = 0;
- } else
- send_boot_notice(HM_ATTACH);
+ no_server = 1;
+ syslog (LOG_INFO, "Server went down, finding new server.");
+ send_flush_notice(HM_DETACH);
+ find_next_server(sugg_serv);
+ if (booting) {
+ send_boot_notice(HM_BOOT);
+ deactivated = 0;
+ } else {
+ send_boot_notice(HM_ATTACH);
+ }
+ disable_queue_retransmits();
}
+
+static void boot_timeout(arg)
+void *arg;
+{
+ new_server(NULL);
+}
+