http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=434452

Should be able to use rdate -o 123 -n w/o needing libnss_files and
/etc/services

rdate currently uses /etc/services to determine ntp ports. For the udeb
in d-i, I'd rather avoid that, since the libnss_files library needed to
read /etc/services is not currently included in d-i, and would use
significant space (33k). Currently if these files are omitted, it fails:

rdate: pool.ntp.org: Servname not supported for ai_socktype.

It seemed to me that if rdate is run with the -o option, it knows the
port to use, and so shouldn't need to look in /etc/services at all.
However the current use of getaddrinfo makes it look in /etc/services
every time. Also, it currently doesn't support -o at all for NTP.

PS: As I was reading the code, I noticed several innacuracies on the
man page:

* -u is not supported for NTP. Probably obvious, to those who know how
  NTP works, but wasn't to me. :-)
* -4 and -6 only select the preferred address family. Ie, with -6, it
  will first try any ipv6 addresses, but if none are found, or
  connecting fails, it will then fall back to ipv4 addresses.

PPS: The package description should mention that it can also use NTP.

Joey Hess <joeyh@debian.org>  Mon, 23 Jul 2007 18:29:43 -0400

diff -up a/src/rfc868time.c b/src/rfc868time.c
--- a/src/rfc868time.c	2006-09-29 12:12:55.000000000 +1000
+++ b/src/rfc868time.c	2009-05-27 11:44:11.000000000 +1000
@@ -69,7 +69,7 @@ static const char rcsid[] = "$OpenBSD: r
 
 void
 rfc868time_client (const char *hostname, int family, struct timeval *new,
-    struct timeval *adjust, int leapflag)
+    struct timeval *adjust, int leapflag, int useudp, int port)
 {
 	struct addrinfo hints, *res0, *res;
 	struct timeval old;
@@ -80,10 +80,10 @@ rfc868time_client (const char *hostname,
 
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = family;
-	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_socktype = useudp ? SOCK_DGRAM : SOCK_STREAM;
 	/* XXX what about rfc868 UDP
 	 * probably not due to the Y2038 issue  -mirabile */
-	error = getaddrinfo(hostname, "time", &hints, &res0);
+	error = getaddrinfo(hostname, port ? NULL : "time", &hints, &res0);
 	if (error) {
 		errx(1, "%s: %s", hostname, gai_strerror(error));
 		/*NOTREACHED*/
@@ -95,6 +95,10 @@ rfc868time_client (const char *hostname,
 		if (s < 0)
 			continue;
 
+		if (port) {
+			((struct sockaddr_in*)res->ai_addr)->sin_port = htons(port);
+		}
+
 		if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
 			close(s);
 			s = -1;
@@ -107,6 +111,10 @@ rfc868time_client (const char *hostname,
 		err(1, "Could not connect socket");
 	freeaddrinfo(res0);
 
+	/* UDP requires us to send an empty datagram first */
+	if (useudp)
+		send(s, NULL, 0, 0);
+
 	if (read(s, &tim, sizeof(tim)) != sizeof(tim))
 		err(1, "Could not read data");
 
diff -up a/src/rdate.c b/src/rdate.c
--- a/src/rdate.c	2006-09-29 12:12:55.000000000 +1000
+++ b/src/rdate.c	2009-05-27 11:44:11.000000000 +1000
@@ -55,6 +55,7 @@ static const char rcsid[] = "$OpenBSD: r
 #include <sys/time.h>
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <ctype.h>
 #include <err.h>
 #include <string.h>
@@ -68,22 +69,24 @@ static const char rcsid[] = "$OpenBSD: r
 #define logwtmp(a,b,c)
 #endif
 
-void rfc868time_client (const char *, int, struct timeval *, struct timeval *, int);
-void ntp_client (const char *, int, struct timeval *, struct timeval *, int);
+void rfc868time_client (const char *, int, struct timeval *, struct timeval *, int, int, int);
+void ntp_client (const char *, int, struct timeval *, struct timeval *, int, int);
 
 extern char    *__progname;
 
 void
 usage(void)
 {
-	(void) fprintf(stderr, "Usage: %s [-46acnpsv] host\n", __progname);
+	(void) fprintf(stderr, "Usage: %s [-46acnpsv] [-o port] host\n", __progname);
 	(void) fprintf(stderr, "  -4: use IPv4 only\n");
 	(void) fprintf(stderr, "  -6: use IPv6 only\n");
 	(void) fprintf(stderr, "  -a: use adjtime instead of instant change\n");
 	(void) fprintf(stderr, "  -c: correct leap second count\n");
 	(void) fprintf(stderr, "  -n: use SNTP instead of RFC868 time protocol\n");
+	(void) fprintf(stderr, "  -o num: override time port with num\n");
 	(void) fprintf(stderr, "  -p: just print, don't set\n");
 	(void) fprintf(stderr, "  -s: just set, don't print\n");
+	(void) fprintf(stderr, "  -u: use UDP instead of TCP as transport\n");
 	(void) fprintf(stderr, "  -v: verbose output\n");
 }
 
@@ -91,15 +94,16 @@ int
 main(int argc, char **argv)
 {
 	int             pr = 0, silent = 0, ntp = 0, verbose = 0;
-	int		slidetime = 0, corrleaps = 0;
+	int		slidetime = 0, corrleaps = 0, useudp = 0;
 	char           *hname;
 	extern int      optind;
 	int             c;
 	int		family = PF_UNSPEC;
+	int		port = 0;
 
 	struct timeval new, adjust;
 
-	while ((c = getopt(argc, argv, "46psancv")) != -1)
+	while ((c = getopt(argc, argv, "46psancvuo:")) != -1)
 		switch (c) {
 		case '4':
 			family = PF_INET;
@@ -133,6 +137,14 @@ main(int argc, char **argv)
 			verbose++;
 			break;
 
+		case 'u':
+			useudp++;
+			break;
+
+		case 'o':
+			port = atoi(optarg);
+			break;
+
 		default:
 			usage();
 			return 1;
@@ -145,9 +157,9 @@ main(int argc, char **argv)
 	hname = argv[optind];
 
 	if (ntp)
-		ntp_client(hname, family, &new, &adjust, corrleaps);
+		ntp_client(hname, family, &new, &adjust, corrleaps, port);
 	else
-		rfc868time_client(hname, family, &new, &adjust, corrleaps);
+		rfc868time_client(hname, family, &new, &adjust, corrleaps, useudp, port);
 
 	if (!pr) {
 		if (!slidetime) {
diff -up a/src/ntp.c b/src/ntp.c
--- a/src/ntp.c	2007-11-11 17:04:33.000000000 +1100
+++ b/src/ntp.c	2009-05-27 11:44:11.000000000 +1000
@@ -110,7 +110,7 @@ struct ntp_data {
 	u_int64_t	xmitck;
 };
 
-void	ntp_client(const char *, int, struct timeval *, struct timeval *, int);
+void	ntp_client(const char *, int, struct timeval *, struct timeval *, int, int);
 int	sync_ntp(int, const struct sockaddr *, double *, double *);
 int	write_packet(int, struct ntp_data *);
 int	read_packet(int, struct ntp_data *, double *, double *);
@@ -126,7 +126,7 @@ int	corrleaps;
 
 void
 ntp_client(const char *hostname, int family, struct timeval *new,
-    struct timeval *adjust, int leapflag)
+    struct timeval *adjust, int leapflag, int port)
 {
 	struct addrinfo hints, *res0, *res;
 	double offset, error;
@@ -135,7 +135,7 @@ ntp_client(const char *hostname, int fam
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = family;
 	hints.ai_socktype = SOCK_DGRAM;
-	ierror = getaddrinfo(hostname, "ntp", &hints, &res0);
+	ierror = getaddrinfo(hostname, port ? NULL : "ntp", &hints, &res0);
 	if (ierror) {
 		errx(1, "%s: %s", hostname, gai_strerror(ierror));
 		/*NOTREACHED*/
@@ -150,6 +150,10 @@ ntp_client(const char *hostname, int fam
 		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
 		if (s < 0)
 			continue;
+		
+		if (port) {
+			((struct sockaddr_in*)res->ai_addr)->sin_port = htons(port);
+		}
 
 		ret = sync_ntp(s, res->ai_addr, &offset, &error);
 		if (ret < 0) {
--- a/docs/rdate.8	2007-11-11 17:04:33.000000000 +1100
+++ b/docs/rdate.8	2009-05-27 11:44:11.000000000 +1000
@@ -3,6 +3,7 @@
 .\"
 .\" Copyright (c) 1994 Christos Zoulas
 .\" All rights reserved.
+.\" Copyright (c) 2007 Anibal Monsalve Salazar
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" modification, are permitted provided that the following conditions
@@ -37,7 +38,8 @@
 .Nd set the system's date from a remote host
 .Sh SYNOPSIS
 .Nm rdate
-.Op Fl 46acnpsv
+.Op Fl 46acnpsuv
+.Op Fl o Ar port
 .Ar host
 .Sh DESCRIPTION
 .Nm
@@ -76,10 +78,16 @@ server (with this parameter) or (recomme
 controlled watch or phone service.
 .It Fl n
 Use SNTP (RFC 2030) instead of the RFC 868 time protocol.
+.It Fl o Ar port
+Use port
+.Ar port
+instead of port 37.
 .It Fl p
 Do not set, just print the remote time.
 .It Fl s
 Do not print the time.
+.It Fl u
+Use UDP instead of TCP as transport.
 .It Fl v
 Verbose output.
 Always show the adjustment.
@@ -108,9 +116,22 @@ To gradually adjust time once an hour af
 adjustment, put the following line into root's crontab:
 .Pp
 .D1 Li "58  *  *  *  *  rdate -ncav ptbtime1.ptb.de | logger -t NTP"
+.Pp
+To to set the time through an ssh tunnel, use something like so:
+.Pp
+.D1 Li ssh -f -L 10037:time.example.com:37 tyr.example.com sleep 10
+.D1 Li rdate -a -o 10037 locahost
+.Pp
 .Sh SEE ALSO
 .Xr date 1 ,
 .Xr adjtime 2 ,
 .Xr inetd 8 ,
 .Xr ntpd 8 ,
 .Xr timed 8
+.Sh AUTHORS
+This
+manual page was written by
+.An Christos Zoulas.
+It was changed by
+.An Anibal Monsalve Salazar
+for the Debian Project.
