* Copyright (c) 1990 The Regents of the University of California.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)netdate.c 5.2 (Berkeley) %G%";
#include <protocols/timed.h>
#define WAITACK 2 /* seconds */
#define WAITDATEACK 5 /* seconds */
* Set the date in the machines controlled by timedaemons by communicating the
* new date to the local timedaemon. If the timedaemon is in the master state,
* it performs the correction on all slaves. If it is in the slave state, it
* notifies the master that a correction is needed.
* Returns 0 on success. Returns > 0 on failure, setting retval to 2;
struct sockaddr_in sin
, dest
, from
;
int s
, length
, port
, timed_ack
, found
, err
;
char hostname
[MAXHOSTNAMELEN
];
if ((sp
= getservbyname("timed", "udp")) == NULL
) {
(void)fprintf(stderr
, "date: udp/timed: unknown service.n");
dest
.sin_port
= sp
->s_port
;
dest
.sin_family
= AF_INET
;
dest
.sin_addr
.s_addr
= htonl((u_long
)INADDR_ANY
);
s
= socket(AF_INET
, SOCK_DGRAM
, 0);
if (errno
!= EPROTONOSUPPORT
)
bzero((char *)&sin
, sizeof(sin
));
sin
.sin_family
= AF_INET
;
for (port
= IPPORT_RESERVED
- 1; port
> IPPORT_RESERVED
/ 2; port
--) {
sin
.sin_port
= htons((u_short
)port
);
if (bind(s
, (struct sockaddr
*)&sin
, sizeof(sin
)) >= 0)
if (errno
!= EADDRNOTAVAIL
)
if (port
== IPPORT_RESERVED
/ 2) {
(void)fprintf(stderr
, "date: all ports in use.\n");
msg
.tsp_type
= TSP_SETDATE
;
msg
.tsp_vers
= TSPVERSION
;
if (gethostname(hostname
, sizeof(hostname
))) {
perror("date: gethostname");
(void)strncpy(msg
.tsp_name
, hostname
, sizeof(hostname
));
msg
.tsp_seq
= htons((u_short
)0);
msg
.tsp_time
.tv_sec
= htonl((u_long
)tval
);
msg
.tsp_time
.tv_usec
= htonl((u_long
)0);
length
= sizeof(struct sockaddr_in
);
if (connect(s
, (struct sockaddr
*)&dest
, length
) < 0) {
if (send(s
, (char *)&msg
, sizeof(struct tsp
), 0) < 0) {
if (errno
!= ECONNREFUSED
)
found
= select(FD_SETSIZE
, &ready
, (fd_set
*)0, (fd_set
*)0, &tout
);
if (!getsockopt(s
, SOL_SOCKET
, SO_ERROR
, (char *)&err
, &length
)
perror("date: send (delayed error)");
if (found
> 0 && FD_ISSET(s
, &ready
)) {
length
= sizeof(struct sockaddr_in
);
if (recvfrom(s
, &msg
, sizeof(struct tsp
), 0,
(struct sockaddr
*)&from
, &length
) < 0) {
if (errno
!= ECONNREFUSED
)
perror("date: recvfrom");
msg
.tsp_seq
= ntohs(msg
.tsp_seq
);
msg
.tsp_time
.tv_sec
= ntohl(msg
.tsp_time
.tv_sec
);
msg
.tsp_time
.tv_usec
= ntohl(msg
.tsp_time
.tv_usec
);
"date: wrong ack received from timed: %s.\n",
"date: can't reach time daemon, time set locally.\n");