* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)readmsg.c 1.1 (Berkeley) %G%";
#include <protocols/timed.h>
* LOOKAT checks if the message is of the requested type and comes from
* the right machine, returning 1 in case of affirmative answer
((((type == TSP_ANY) || (type == (msg).tsp_type)) && \
((machfrom == NULL) || (strcmp(machfrom, (msg).tsp_name) == 0))) \
((rtime.tv_sec > rtout.tv_sec || (rtime.tv_sec == rtout.tv_sec && \
rtime.tv_usec >= rtout.tv_usec)) \
struct timeval rtime
, rwait
, rtout
;
struct tsplist
*ptr
, *prev
;
* `readmsg' returns message `type' sent by `machfrom' if it finds it
* either in the receive queue, or in a linked list of previously received
* messages that it maintains.
* Otherwise it waits to see if the appropriate message arrives within
* `intvl' seconds. If not, it returns NULL.
struct tsp
*readmsg(type
, machfrom
, intvl
)
static struct tsplist
*head
= &msgslist
;
static struct tsplist
*tail
= &msgslist
;
char *malloc(), *strcpy();
int bytenetorder(), bytehostorder();
fprintf(fd
, "msgqueue:\n");
* Look for the requested message scanning through the
* linked list. If found, return it and free the space
ret
= (struct tsp
*)malloc(sizeof(struct tsp
));
* If the message was not in the linked list, it may still be
* coming from the network. Set the timer and wait
* on a select to read the next incoming message: if it is the
* right one, return it, otherwise insert it in the linked list.
(void)gettimeofday(&rtime
, (struct timezone
*)0);
rtout
.tv_sec
= rtime
.tv_sec
+ intvl
->tv_sec
;
rtout
.tv_usec
= rtime
.tv_usec
+ intvl
->tv_usec
;
if (rtout
.tv_usec
> 1000000) {
rtout
.tv_usec
-= 1000000;
rwait
.tv_sec
= rtout
.tv_sec
- rtime
.tv_sec
;
rwait
.tv_usec
= rtout
.tv_usec
- rtime
.tv_usec
;
rwait
.tv_usec
+= 1000000;
rwait
.tv_sec
= rwait
.tv_usec
= 0;
fprintf(fd
, "readmsg: wait: (%d %d)\n",
rwait
.tv_sec
, rwait
.tv_usec
);
found
= select(20, &ready
, (int *)0, (int *)0, &rwait
);
length
= sizeof(struct sockaddr_in
);
if (recvfrom(sock
, (char *)&msgin
, sizeof(struct tsp
),
0, &from
, &length
) < 0) {
syslog(LOG_ERR
, "timed: receiving datagram packet: %m");
* Should check here to see if message comes from local net.
* Until done, master cannot run on gateway conneting
* two subnets each with running timedaemons.
* Throw away messages coming from this machine, unless
* they are of some particular type.
* This gets rid of broadcast messages and reduces
* master processing time.
if ( !(strcmp(msgin
.tsp_name
, hostname
) != 0 ||
msgin
.tsp_type
== TSP_DATE
||
msgin
.tsp_type
== TSP_TEST
||
msgin
.tsp_type
== TSP_MSITE
||
msgin
.tsp_type
== TSP_TRACEON
||
msgin
.tsp_type
== TSP_TRACEOFF
)) {
fprintf(fd
, "readmsg: discarded: ");
(void)gettimeofday(&rtime
,(struct timezone
*)0);
* Send acknowledgements here; this is faster and avoids
* deadlocks that would occur if acks were sent from a
* higher level routine. Different acknowledgements are
* necessary, depending on status.
tail
->p
= (struct tsplist
*)
malloc(sizeof(struct tsplist
));
(void)gettimeofday(&rtime
, (struct timezone
*)0);
fprintf(fd
, "readmsg: ");
* `slaveack' sends the necessary acknowledgements:
* only the type ACK is to be sent by a slave
length
= sizeof(struct sockaddr_in
);
resp
.tsp_vers
= TSPVERSION
;
(void)strcpy(resp
.tsp_name
, hostname
);
bytenetorder(&resp
); /* this is not really necessary here */
if (sendto(sock
, (char *)&resp
, sizeof(struct tsp
), 0,
syslog(LOG_ERR
, "timed: sendto: %m");
* `masterack' sends the necessary acknowledgments
* to the messages received by a master
length
= sizeof(struct sockaddr_in
);
resp
.tsp_vers
= TSPVERSION
;
(void)strcpy(resp
.tsp_name
, hostname
);
bytenetorder(&resp
); /* this is not really necessary here */
if (sendto(sock
, (char *)&resp
, sizeof(struct tsp
), 0,
syslog(LOG_ERR
, "timed: sendto: %m");
resp
.tsp_type
= TSP_MASTERACK
;
if (sendto(sock
, (char *)&resp
, sizeof(struct tsp
), 0,
syslog(LOG_ERR
, "timed: sendto: %m");
resp
.tsp_type
= TSP_DATEACK
;
if (sendto(sock
, (char *)&resp
, sizeof(struct tsp
), 0,
syslog(LOG_ERR
, "timed: sendto: %m");
fprintf(fd
, "%s %d %d (%d, %d) %s\n",