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
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$";
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(ZNotice_t *notice);
34 static Code_t dump_queue(void);
35 static void queue_timeout(void *arg);
37 int rexmit_times[] = { 2, 2, 4, 4, 8, -1 };
40 Code_t dump_queue(void);
51 timer_reset(q->timer);
57 DPR("Queue initialized and flushed.\n");
61 add_notice_to_queue(ZNotice_t *notice,
63 struct sockaddr_in *repl,
68 DPR("Adding notice to queue...\n");
69 if (!find_notice_in_queue(notice)) {
70 entry = (Queue *) malloc(sizeof(Queue));
72 return(ZERR_NONOTICE);
74 entry->packet = (char *) malloc(Z_MAXPKTLEN);
75 if (entry->packet == NULL) {
77 return(ZERR_NONOTICE);
79 memcpy(entry->packet, packet, Z_MAXPKTLEN);
80 if (ZParseNotice(entry->packet, len, &entry->notice) != ZERR_NONE) {
81 syslog(LOG_ERR, "ZParseNotice failed, but succeeded before");
85 LIST_INSERT(&hm_queue, entry);
87 entry->timer = (retransmits_enabled) ?
88 timer_set_rel(rexmit_times[0], queue_timeout, entry) : NULL;
94 remove_notice_from_queue(ZNotice_t *notice,
96 struct sockaddr_in *repl)
100 DPR("Removing notice from queue...\n");
101 entry = find_notice_in_queue(notice);
103 return(ZERR_NONOTICE);
105 *kind = entry->notice.z_kind;
106 *repl = entry->reply;
108 timer_reset(entry->timer);
118 /* We have a server; transmit all of our packets. */
120 retransmit_queue(struct sockaddr_in *sin)
125 DPR("Retransmitting queue to new server...\n");
126 ret = ZSetDestAddr(sin);
127 if (ret != ZERR_NONE) {
129 com_err("queue", ret, "setting destination");
131 for (entry = hm_queue; entry; entry = entry->next) {
133 DPR2("\tz_kind: %d\n", entry->notice.z_kind);
134 DPR2("\tz_port: %u\n", ntohs(entry->notice.z_port));
135 DPR2("\tz_class: %s\n", entry->notice.z_class);
136 DPR2("\tz_clss_inst: %s\n", entry->notice.z_class_inst);
137 DPR2("\tz_opcode: %s\n", entry->notice.z_opcode);
138 DPR2("\tz_sender: %s\n", entry->notice.z_sender);
139 DPR2("\tz_recip: %s\n", entry->notice.z_recipient);
140 ret = send_outgoing(&entry->notice);
141 if (ret != ZERR_NONE) {
143 com_err("queue", ret, "sending raw notice");
145 entry->timer = timer_set_rel(rexmit_times[0], queue_timeout, entry);
148 retransmits_enabled = 1;
151 /* We lost our server; nuke all of our timers. */
153 disable_queue_retransmits(void)
157 for (entry = hm_queue; entry; entry = entry->next) {
159 timer_reset(entry->timer);
162 retransmits_enabled = 0;
173 DPR("Dumping queue...\n");
175 printf("Queue is empty.\n");
179 for (entry = hm_queue; entry; entry = entry->next) {
181 printf("\tz_kind: %d\n", entry->notice.z_kind);
182 printf("\tz_port: %u\n", ntohs(entry->notice.z_port));
183 printf("\tz_class: %s\n", entry->notice.z_class);
184 printf("\tz_clss_inst: %s\n", entry->notice.z_class_inst);
185 printf("\tz_opcode: %s\n", entry->notice.z_opcode);
186 printf("\tz_sender: %s\n", entry->notice.z_sender);
187 printf("\tz_recip: %s\n", entry->notice.z_recipient);
188 printf("\tMessage:\n");
189 mp = entry->notice.z_message;
190 for (ml = strlen(mp) + 1; ml <= entry->notice.z_message_len; ml++) {
191 printf("\t%s\n", mp);
205 for (entry = hm_queue; entry; entry = entry->next)
211 find_notice_in_queue(ZNotice_t *notice)
215 for (entry = hm_queue; entry; entry = entry->next) {
216 if (ZCompareUID(&entry->notice.z_uid, ¬ice->z_uid))
223 queue_timeout(void *arg)
225 Queue *entry = (Queue *) arg;
229 ret = ZSetDestAddr(&serv_sin);
230 if (ret != ZERR_NONE) {
232 com_err("queue", ret, "setting destination");
235 if (rexmit_times[entry->retries] == -1) {
239 DPR("Resending notice:\n");
240 DPR2("\tz_kind: %d\n", entry->notice.z_kind);
241 DPR2("\tz_port: %u\n", ntohs(entry->notice.z_port));
242 DPR2("\tz_class: %s\n", entry->notice.z_class);
243 DPR2("\tz_clss_inst: %s\n", entry->notice.z_class_inst);
244 DPR2("\tz_opcode: %s\n", entry->notice.z_opcode);
245 DPR2("\tz_sender: %s\n", entry->notice.z_sender);
246 DPR2("\tz_recip: %s\n", entry->notice.z_recipient);
247 ret = send_outgoing(&entry->notice);
248 if (ret != ZERR_NONE) {
250 com_err("queue", ret, "sending raw notice");
252 entry->timer = timer_set_rel(rexmit_times[entry->retries], queue_timeout,