* Copyright (c) 1985, 1987, 1988 The Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1985, 1987, 1988 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)date.c 4.25 (Berkeley) %G%";
* Date - print and set date
#define ATOI2(ar) (ar[0] - '0') * 10 + (ar[1] - '0'); ar += 2;
static struct timeval tv
;
{ -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
char *username
, *getlogin();
tz
.tz_dsttime
= tz
.tz_minuteswest
= 0;
while ((ch
= getopt(argc
, argv
, "d:nut:")) != EOF
)
case 'd': /* daylight savings time */
tz
.tz_dsttime
= atoi(optarg
) ? 1 : 0;
case 'n': /* don't set network */
case 'u': /* do it in GMT */
case 't': /* minutes west of GMT */
/* error check; we can't allow "PST" */
tz
.tz_minuteswest
= atoi(optarg
);
if ((tz
.tz_minuteswest
|| tz
.tz_dsttime
) &&
settimeofday((struct timeval
*)NULL
, &tz
)) {
perror("date: settimeofday");
if (gettimeofday(&tv
, &tz
)) {
perror("date: gettimeofday");
if (!uflag
) { /* convert to GMT assuming local time */
tv
.tv_sec
+= (long)tz
.tz_minuteswest
* SECSPERMIN
;
/* now fix up local daylight time */
if (localtime((time_t *)&tv
.tv_sec
)->tm_isdst
)
tv
.tv_sec
-= SECSPERHOUR
;
if (nflag
|| !netsettime(tv
)) {
logwtmp("|", "date", "");
if (settimeofday(&tv
, (struct timezone
*)NULL
)) {
perror("date: settimeofday");
logwtmp("{", "date", "");
if (!username
|| *username
== '\0') /* single-user or no tty */
syslog(LOG_AUTH
| LOG_NOTICE
, "date set by %s", username
);
if (gettimeofday(&tv
, (struct timezone
*)NULL
)) {
perror("date: gettimeofday");
ap
= asctime(gmtime((time_t *)&tv
.tv_sec
));
tp
= localtime((time_t *)&tv
.tv_sec
);
printf("%.20s%s%s", ap
, tzn
, ap
+ 19);
* convert user's time into number of seconds
register int year
, month
;
int day
, hour
, mins
, secs
;
for (secs
= 0, C
= ap
; *C
; ++C
) {
if (*C
== '.') { /* seconds provided */
secs
= (C
[1] - '0') * 10 + (C
[2] - '0');
L
= localtime((time_t *)&tv
.tv_sec
);
year
= L
->tm_year
; /* defaults */
switch ((int)(C
- ap
)) { /* length */
case 10: /* yymmddhhmm */
if (*ap
|| month
< 1 || month
> 12 || day
< 1 || day
> 31 ||
hour
< 0 || hour
> 23 || mins
< 0 || mins
> 59 ||
if (isleap(year
) && month
> 2)
for (--year
;year
>= EPOCH_YEAR
;--year
)
tv
.tv_sec
+= isleap(year
) ? DAYSPERLYEAR
: DAYSPERNYEAR
;
tv
.tv_sec
+= dmsize
[month
];
tv
.tv_sec
= HOURSPERDAY
* tv
.tv_sec
+ hour
;
tv
.tv_sec
= MINSPERHOUR
* tv
.tv_sec
+ mins
;
tv
.tv_sec
= SECSPERMIN
* tv
.tv_sec
+ secs
;
#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 1 on success, 0 on failure.
int s
, length
, port
, timed_ack
, found
, err
;
char hostname
[MAXHOSTNAMELEN
];
struct sockaddr_in sin
, dest
, from
;
sp
= getservbyname("timed", "udp");
fputs("udp/timed: unknown service\n", stderr
);
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
!= EADDRINUSE
) {
if (errno
!= EADDRNOTAVAIL
)
if (port
== IPPORT_RESERVED
/ 2) {
fputs("date: All ports in use\n", stderr
);
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
)ntv
.tv_sec
);
msg
.tsp_time
.tv_usec
= htonl((u_long
)ntv
.tv_usec
);
length
= sizeof (struct sockaddr_in
);
if (connect(s
, &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
) == 0
if (errno
!= ECONNREFUSED
)
perror("date: send (delayed error)");
if (found
> 0 && FD_ISSET(s
, &ready
)) {
length
= sizeof (struct sockaddr_in
);
if (recvfrom(s
, (char *)&msg
, sizeof (struct tsp
), 0, &from
,
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",
fputs("date: Can't reach time daemon, time set locally.\n",
fputs("usage: date [-nu] [-d dst] [-t minutes_west] [yymmddhhmm[.ss]]\n", stderr
);