1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains the hostmanager queueing routines.
4 * Created by: David C. Jedlinsky
6 * $Id: queue.c,v 1.22 1999/10/20 16:44:11 ghudson Exp $
8 * Copyright (c) 1987 by the Massachusetts Institute of Technology.
9 * For copying and distribution information, see the file
17 static char rcsid_queue_c[] = "$Id: queue.c,v 1.22 1999/10/20 16:44:11 ghudson Exp $";
21 typedef struct _Queue {
26 struct sockaddr_in reply;
27 struct _Queue *next, **prev_p;
30 static Queue *hm_queue;
31 static int retransmits_enabled = 0;
33 static Queue *find_notice_in_queue __P((ZNotice_t *notice));
34 static Code_t dump_queue __P((void));
35 static void queue_timeout __P((void *arg));
37 int rexmit_times[] = { 2, 2, 4, 4, 8, -1 };
50 timer_reset(q->timer);
56 DPR("Queue initialized and flushed.\n");
59 Code_t add_notice_to_queue(notice, packet, repl, len)
62 struct sockaddr_in *repl;
67 DPR("Adding notice to queue...\n");
68 if (!find_notice_in_queue(notice)) {
69 entry = (Queue *) malloc(sizeof(Queue));
71 return(ZERR_NONOTICE);
73 entry->packet = (char *) malloc(Z_MAXPKTLEN);
74 if (entry->packet == NULL) {
76 return(ZERR_NONOTICE);
78 memcpy(entry->packet, packet, Z_MAXPKTLEN);
79 if (ZParseNotice(entry->packet, len, &entry->notice) != ZERR_NONE) {
80 syslog(LOG_ERR, "ZParseNotice failed, but succeeded before");
84 LIST_INSERT(&hm_queue, entry);
86 entry->timer = (retransmits_enabled) ?
87 timer_set_rel(rexmit_times[0], queue_timeout, entry) : NULL;
92 Code_t remove_notice_from_queue(notice, kind, repl)
95 struct sockaddr_in *repl;
99 DPR("Removing notice from queue...\n");
100 entry = find_notice_in_queue(notice);
102 return(ZERR_NONOTICE);
104 *kind = entry->notice.z_kind;
105 *repl = entry->reply;
107 timer_reset(entry->timer);
117 /* We have a server; transmit all of our packets. */
118 void retransmit_queue(sin)
119 struct sockaddr_in *sin;
124 DPR("Retransmitting queue to new server...\n");
125 ret = ZSetDestAddr(sin);
126 if (ret != ZERR_NONE) {
128 com_err("queue", ret, "setting destination");
130 for (entry = hm_queue; entry; entry = entry->next) {
132 DPR2("\tz_kind: %d\n", entry->notice.z_kind);
133 DPR2("\tz_port: %u\n", ntohs(entry->notice.z_port));
134 DPR2("\tz_class: %s\n", entry->notice.z_class);
135 DPR2("\tz_clss_inst: %s\n", entry->notice.z_class_inst);
136 DPR2("\tz_opcode: %s\n", entry->notice.z_opcode);
137 DPR2("\tz_sender: %s\n", entry->notice.z_sender);
138 DPR2("\tz_recip: %s\n", entry->notice.z_recipient);
139 ret = send_outgoing(&entry->notice);
140 if (ret != ZERR_NONE) {
142 com_err("queue", ret, "sending raw notice");
144 entry->timer = timer_set_rel(rexmit_times[0], queue_timeout, entry);
147 retransmits_enabled = 1;
150 /* We lost our server; nuke all of our timers. */
151 void disable_queue_retransmits()
155 for (entry = hm_queue; entry; entry = entry->next) {
157 timer_reset(entry->timer);
160 retransmits_enabled = 0;
164 static Code_t dump_queue()
170 DPR("Dumping queue...\n");
172 printf("Queue is empty.\n");
176 for (entry = hm_queue; entry; entry = entry->next) {
178 printf("\tz_kind: %d\n", entry->notice.z_kind);
179 printf("\tz_port: %u\n", ntohs(entry->notice.z_port));
180 printf("\tz_class: %s\n", entry->notice.z_class);
181 printf("\tz_clss_inst: %s\n", entry->notice.z_class_inst);
182 printf("\tz_opcode: %s\n", entry->notice.z_opcode);
183 printf("\tz_sender: %s\n", entry->notice.z_sender);
184 printf("\tz_recip: %s\n", entry->notice.z_recipient);
185 printf("\tMessage:\n");
186 mp = entry->notice.z_message;
187 for (ml = strlen(mp) + 1; ml <= entry->notice.z_message_len; ml++) {
188 printf("\t%s\n", mp);
201 for (entry = hm_queue; entry; entry = entry->next)
206 static Queue *find_notice_in_queue(notice)
211 for (entry = hm_queue; entry; entry = entry->next) {
212 if (ZCompareUID(&entry->notice.z_uid, ¬ice->z_uid))
218 static void queue_timeout(arg)
221 Queue *entry = (Queue *) arg;
225 ret = ZSetDestAddr(&serv_sin);
226 if (ret != ZERR_NONE) {
228 com_err("queue", ret, "setting destination");
231 if (rexmit_times[entry->retries] == -1) {
235 DPR("Resending notice:\n");
236 DPR2("\tz_kind: %d\n", entry->notice.z_kind);
237 DPR2("\tz_port: %u\n", ntohs(entry->notice.z_port));
238 DPR2("\tz_class: %s\n", entry->notice.z_class);
239 DPR2("\tz_clss_inst: %s\n", entry->notice.z_class_inst);
240 DPR2("\tz_opcode: %s\n", entry->notice.z_opcode);
241 DPR2("\tz_sender: %s\n", entry->notice.z_sender);
242 DPR2("\tz_recip: %s\n", entry->notice.z_recipient);
243 ret = send_outgoing(&entry->notice);
244 if (ret != ZERR_NONE) {
246 com_err("queue", ret, "sending raw notice");
248 entry->timer = timer_set_rel(rexmit_times[entry->retries], queue_timeout,