Add ntpd port.

This commit is contained in:
Jonas 'Sortie' Termansen 2022-03-06 15:34:05 +01:00
parent 693f57a0e3
commit e3ef3cfadd
11 changed files with 948 additions and 4 deletions

View File

@ -125,6 +125,7 @@ mkdir -p boot/grub/init
echo "furthermore" > boot/grub/init/furthermore
# TODO: Possibly use a 'try' feature to not warn in case it was already unset.
echo "unset require dhclient" > boot/grub/init/network-no-dhclient
echo "require ntpd optional" > boot/grub/init/local-ntpd
echo "require sshd optional" > boot/grub/init/local-sshd
exec > boot/grub/grub.cfg
@ -194,6 +195,7 @@ fi
set enable_src=true
set enable_network_drivers=
set enable_dhclient=true
set enable_ntpd=false
set enable_sshd=false
export version
@ -206,6 +208,7 @@ export no_random_seed
export enable_src
export enable_network_drivers
export enable_dhclient
export enable_ntpd
export enable_sshd
EOF
@ -302,6 +305,13 @@ cat << EOF
module /boot/grub/init/network-no-dhclient --append-to /etc/init/network
echo done
fi
if \$enable_ntpd; then
echo -n "Enabling ntpd ... "
module /boot/grub/init/local-ntpd --append-to /etc/init/local
module /boot/grub/init/furthermore --create-to /etc/init/time
module /boot/grub/init/local-ntpd --append-to /etc/init/time
echo done
fi
if \$enable_sshd; then
echo -n "Enabling sshd ... "
module /boot/grub/init/local-sshd --append-to /etc/init/local
@ -466,6 +476,18 @@ else
}
fi
if \$enable_ntpd; then
menuentry "Disable NTP client" {
enable_ntpd=false
configfile /boot/grub/advanced.cfg
}
else
menuentry "Enable NTP client" {
enable_ntpd=true
configfile /boot/grub/advanced.cfg
}
fi
if \$enable_sshd; then
menuentry "Disable SSH server" {
enable_sshd=false

View File

@ -1,3 +1,3 @@
set_minimal="cut dash e2fsprogs grep grub mdocml sed xargs"
set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip libcurl libcurses libssl libstdc++ nano make patch pkg-config python ssh tar vim wget xz xorriso"
set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip libcurl libcurses libssl libstdc++ nano ntpd make patch pkg-config python ssh tar vim wget xz xorriso"
sets="basic minimal"

805
ports/ntpd/ntpd.patch Normal file
View File

@ -0,0 +1,805 @@
diff -Paur --no-dereference -- ntpd.upstream/compat/bsd-setresuid.c ntpd/compat/bsd-setresuid.c
--- ntpd.upstream/compat/bsd-setresuid.c
+++ ntpd/compat/bsd-setresuid.c
@@ -44,6 +44,7 @@
return -1;
# endif
+#if !defined(__sortix__)
/*
* When real, effective and saved uids are the same and we have
* changed uids, sanity check that we cannot restore the old uid.
@@ -62,6 +63,7 @@
errno = EACCES;
return -1;
}
+#endif
return ret;
}
diff -Paur --no-dereference -- ntpd.upstream/compat/imsg-buffer.c ntpd/compat/imsg-buffer.c
--- ntpd.upstream/compat/imsg-buffer.c
+++ ntpd/compat/imsg-buffer.c
@@ -27,6 +27,10 @@
#include <string.h>
#include <unistd.h>
+#if defined(__sortix__) && !defined(IOV_MAX)
+#include <sortix/limits.h>
+#endif
+
#include "imsg.h"
static int ibuf_realloc(struct ibuf *, size_t);
@@ -252,7 +256,7 @@
msg.msg_iovlen = i;
if (buf != NULL && buf->fd != -1) {
- msg.msg_control = (caddr_t)&cmsgbuf.buf;
+ msg.msg_control = (char*)&cmsgbuf.buf;
msg.msg_controllen = sizeof(cmsgbuf.buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
diff -Paur --no-dereference -- ntpd.upstream/include/imsg.h ntpd/include/imsg.h
--- ntpd.upstream/include/imsg.h
+++ ntpd/include/imsg.h
@@ -23,6 +23,8 @@
#include <stdint.h>
+typedef unsigned char u_char;
+
#define IBUF_READ_SIZE 65535
#define IMSG_HEADER_SIZE sizeof(struct imsg_hdr)
#define MAX_IMSGSIZE 16384
diff -Paur --no-dereference -- ntpd.upstream/include/machine/endian.h ntpd/include/machine/endian.h
--- ntpd.upstream/include/machine/endian.h
+++ ntpd/include/machine/endian.h
@@ -32,7 +32,7 @@
#include <sys/endian.h>
#else
-#include_next <machine/endian.h>
+#include <endian.h>
#endif
diff -Paur --no-dereference -- ntpd.upstream/Makefile.in ntpd/Makefile.in
--- ntpd.upstream/Makefile.in
+++ ntpd/Makefile.in
@@ -824,17 +824,14 @@
install-exec-hook:
- @if [ ! -f "$(DESTDIR)$(sysconfdir)/ntpd.conf" ]; then \
- $(INSTALL) -m 644 "$(srcdir)/ntpd.conf" "$(DESTDIR)$(sysconfdir)/ntpd.conf"; \
- else \
- echo; \
- echo " $(DESTDIR)$(sysconfdir)/ntpd.conf already exists, install will not overwrite"; \
- fi
+ $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/default"
+ $(INSTALL) -m 644 "$(srcdir)/ntpd.conf" "$(DESTDIR)$(sysconfdir)/default/ntpd.conf"
+ $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/default/passwd.d"
+ echo "_ntp:x:101:101:_ntp:/var/empty:sh" > "$(DESTDIR)$(sysconfdir)/default/passwd.d/ntpd"
+ $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/default/group.d"
+ echo "_ntp::101:_ntp" > "$(DESTDIR)$(sysconfdir)/default/group.d/ntpd"
uninstall-local:
- @if cmp -s "$(DESTDIR)$(sysconfdir)/ntpd.conf" "$(srcdir)/ntpd.conf"; then \
- rm -f "$(DESTDIR)$(sysconfdir)/ntpd.conf"; \
- fi
@rm -f "$(DESTDIR)$(sbindir)/ntpctl"
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff -Paur --no-dereference -- ntpd.upstream/src/client.c ntpd/src/client.c
--- ntpd.upstream/src/client.c
+++ ntpd/src/client.c
@@ -128,7 +128,9 @@
int
client_query(struct ntp_peer *p)
{
+#ifdef IPTOS_LOWDELAY
int val;
+#endif
if (p->addr == NULL && client_nextaddr(p) == -1) {
if (conf->settime)
@@ -189,10 +191,12 @@
} else
fatal("client_query connect");
}
+#ifdef IPTOS_LOWDELAY
val = IPTOS_LOWDELAY;
if (p->addr->ss.ss_family == AF_INET && setsockopt(p->query->fd,
IPPROTO_IP, IP_TOS, &val, sizeof(val)) == -1)
log_warn("setsockopt IPTOS_LOWDELAY");
+#endif
#ifdef SO_TIMESTAMP
val = 1;
if (setsockopt(p->query->fd, SOL_SOCKET, SO_TIMESTAMP,
@@ -307,7 +311,10 @@
somsg.msg_controllen = sizeof(cmsgbuf.buf);
if ((size = recvmsg(p->query->fd, &somsg, 0)) == -1) {
- if (errno == EHOSTUNREACH || errno == EHOSTDOWN ||
+ if (errno == EHOSTUNREACH ||
+#ifdef EHOSTDOWN
+ errno == EHOSTDOWN ||
+#endif
errno == ENETUNREACH || errno == ENETDOWN ||
errno == ECONNREFUSED || errno == EADDRNOTAVAIL ||
errno == ENOPROTOOPT || errno == ENOENT) {
@@ -405,10 +412,11 @@
if (p->reply[p->shift].delay < 0) {
interval = error_interval();
set_next(p, interval);
- log_info("reply from %s: negative delay %fs, "
+ log_info("reply from %s: negative delay %llims, "
"next query %llds",
log_sockaddr((struct sockaddr *)&p->addr->ss),
- p->reply[p->shift].delay, (long long)interval);
+ (long long)(p->reply[p->shift].delay * 1000.0),
+ (long long)interval);
return (0);
}
p->reply[p->shift].error = (T2 - T1) - (T3 - T4);
@@ -470,10 +478,10 @@
else
interval = scale_interval(INTERVAL_QUERY_NORMAL);
- log_debug("reply from %s: offset %f delay %f, "
+ log_debug("reply from %s: offset %llims delay %llims, "
"next query %llds",
log_sockaddr((struct sockaddr *)&p->addr->ss),
- offset, delay,
+ (long long)(offset * 1000), (long long)(delay * 1000),
(long long)interval);
set_next(p, interval);
diff -Paur --no-dereference -- ntpd.upstream/src/config.c ntpd/src/config.c
--- ntpd.upstream/src/config.c
+++ ntpd/src/config.c
@@ -25,7 +25,9 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#if __has_include(<resolv.h>)
#include <resolv.h>
+#endif
#include <unistd.h>
#include "ntpd.h"
diff -Paur --no-dereference -- ntpd.upstream/src/constraint.c ntpd/src/constraint.c
--- ntpd.upstream/src/constraint.c
+++ ntpd/src/constraint.c
@@ -48,6 +48,10 @@
#define IMF_FIXDATE "%a, %d %h %Y %T GMT"
#define X509_DATE "%Y-%m-%d %T UTC"
+#if defined(__sortix__)
+#define setgroups(a, b) ((void) (a), (void) (b), 0)
+#endif
+
int constraint_addr_init(struct constraint *);
void constraint_addr_head_clear(struct constraint *);
struct constraint *
@@ -265,7 +269,8 @@
constraint_add(cstr);
constraint_cnt++;
- if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, AF_UNSPEC,
+ /* PATCH: AF_UNIX SOCK_DGRAM isn't implemented on Sortix. */
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, AF_UNSPEC,
pipes) == -1)
fatal("%s pipes", __func__);
@@ -683,9 +688,9 @@
offset = gettime_from_timeval(&tv[0]) -
gettime_from_timeval(&tv[1]);
- log_info("constraint reply from %s: offset %f",
+ log_info("constraint reply from %s: offset %lli ms",
log_sockaddr((struct sockaddr *)&cstr->addr->ss),
- offset);
+ (long long)(offset * 1000));
cstr->state = STATE_REPLY_RECEIVED;
cstr->last = getmonotime();
diff -Paur --no-dereference -- ntpd.upstream/src/control.c ntpd/src/control.c
--- ntpd.upstream/src/control.c
+++ ntpd/src/control.c
@@ -42,7 +42,7 @@
struct sockaddr_un saddr;
int fd;
- bzero(&saddr, sizeof(saddr));
+ memset(&saddr, 0, sizeof(saddr));
saddr.sun_family = AF_UNIX;
strlcpy(saddr.sun_path, path, sizeof(saddr.sun_path));
@@ -97,10 +97,12 @@
umask(old_umask);
if (chmod(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
+#if !defined(__sortix__)
log_warn("control_init: chmod");
close(fd);
(void)unlink(path);
return (-1);
+#endif
}
session_socket_nonblockmode(fd);
diff -Paur --no-dereference -- ntpd.upstream/src/init/ntpd ntpd/src/init/ntpd
--- ntpd.upstream/src/init/ntpd
+++ ntpd/src/init/ntpd
@@ -0,0 +1,4 @@
+require network
+#program=ntpd
+#exec $program -d
+exec ntpd -d
diff -Paur --no-dereference -- ntpd.upstream/src/Makefile.in ntpd/src/Makefile.in
--- ntpd.upstream/src/Makefile.in
+++ ntpd/src/Makefile.in
@@ -1003,6 +1003,8 @@
info-am:
install-data-am: install-man
+ mkdir -p $(DESTDIR)$(datadir)/init
+ cp init/ntpd $(DESTDIR)$(datadir)/init/ntpd
install-dvi: install-dvi-am
diff -Paur --no-dereference -- ntpd.upstream/src/ntp.c ntpd/src/ntp.c
--- ntpd.upstream/src/ntp.c
+++ ntpd/src/ntp.c
@@ -20,6 +20,7 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
@@ -35,6 +36,10 @@
#include "ntpd.h"
+#if defined(__sortix__)
+#define setgroups(a, b) ((void) (a), (void) (b), 0)
+#endif
+
#define PFD_PIPE_MAIN 0
#define PFD_PIPE_DNS 1
#define PFD_SOCK_CTL 2
@@ -79,7 +84,9 @@
u_int listener_cnt, new_cnt, sent_cnt, trial_cnt;
u_int ctl_cnt;
struct pollfd *pfd = NULL;
+#if !defined(__sortix__)
struct servent *se;
+#endif
struct listen_addr *la;
struct ntp_peer *p;
struct ntp_peer **idx2peer = NULL;
@@ -96,7 +103,7 @@
pipe_dns) == -1)
fatal("socketpair");
- start_child(NTPDNS_PROC_NAME, pipe_dns[1], argc, argv);
+ pid_t dns_pid = start_child(NTPDNS_PROC_NAME, pipe_dns[1], argc, argv);
log_init(nconf->debug ? LOG_TO_STDERR : LOG_TO_SYSLOG, nconf->verbose,
LOG_DAEMON);
@@ -104,8 +111,10 @@
fatal("setsid");
log_procinit("ntp");
+#if !defined(__sortix__)
if ((se = getservbyname("ntp", "udp")) == NULL)
fatal("getservbyname");
+#endif
/* Start control socket. */
if ((fd_ctl = control_init(CTLSOCKET)) == -1)
@@ -137,14 +146,20 @@
setproctitle("ntp engine");
conf = nconf;
+#if defined(__sortix__)
+ setup_listeners(NULL, conf, &listener_cnt);
+#else
setup_listeners(se, conf, &listener_cnt);
+#endif
if (setgroups(1, &pw->pw_gid) ||
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("can't drop privileges");
+#if !defined(__sortix__)
endservent();
+#endif
/* The ntp process will want to open NTP client sockets -> "inet" */
if (pledge("stdio inet", NULL) == -1)
@@ -464,6 +479,9 @@
msgbuf_clear(&ibuf_dns->w);
free(ibuf_dns);
+ kill(dns_pid, SIGTERM);
+ waitpid(dns_pid, NULL, 0);
+
log_info("ntp engine exiting");
exit(0);
}
diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.c ntpd/src/ntpd.c
--- ntpd.upstream/src/ntpd.c
+++ ntpd/src/ntpd.c
@@ -45,6 +45,107 @@
#include "ntpd.h"
+#if defined(__sortix__)
+#include <timespec.h>
+
+int adjtime(const struct timeval *delta, struct timeval *olddelta)
+{
+ if (delta) {
+ struct timespec deltats = {
+ .tv_sec = delta->tv_sec,
+ .tv_nsec = delta->tv_usec * 1000
+ };
+ struct timespec oldnow;
+ if (clock_gettime(CLOCK_REALTIME, &oldnow) < 0)
+ return -1;
+ struct timespec newnow = timespec_add(oldnow, deltats);
+ if (clock_settime(CLOCK_REALTIME, &newnow) < 0)
+ return -1;
+ }
+ if (olddelta) {
+ olddelta->tv_sec = 0;
+ olddelta->tv_usec = 0;
+ }
+ return 0;
+}
+
+/*
+From musl:
+
+Copyright © 2005-2014 Rich Felker, et al.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+int daemon(int nochdir, int noclose)
+{
+ if (!nochdir && chdir("/"))
+ return -1;
+ if (!noclose) {
+ int fd, failed = 0;
+ if ((fd = open("/dev/null", O_RDWR)) < 0) return -1;
+ if (dup2(fd, 0) < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0)
+ failed++;
+ if (fd > 2) close(fd);
+ if (failed) return -1;
+ }
+
+ switch(fork()) {
+ case 0: break;
+ case -1: return -1;
+ default: _exit(0);
+ }
+
+ if (setsid() < 0) return -1;
+
+ switch(fork()) {
+ case 0: break;
+ case -1: return -1;
+ default: _exit(0);
+ }
+
+ return 0;
+}
+
+int
+adjfreq(const int64_t *freq, int64_t *oldfreq)
+{
+ (void) freq;
+ (void) oldfreq;
+ //log_warnx("adjfreq is not implemented");
+ if (oldfreq)
+ *oldfreq = 0;
+ return 0;
+}
+
+/*
+ * The RTC is only updated if the clock is not marked as unsynced.
+ */
+
+void
+update_time_sync_status(int synced)
+{
+ (void) synced;
+ //log_warnx("update_time_sync_status is not implemented");
+}
+#endif
+
void sighdlr(int);
__dead void usage(void);
int auto_preconditions(const struct ntpd_conf *);
@@ -70,6 +171,7 @@
volatile sig_atomic_t sigchld = 0;
struct imsgbuf *ibuf;
int timeout = INFTIM;
+int readyfd = -1;
extern u_int constraint_cnt;
@@ -108,6 +210,17 @@
}
}
+void
+ready(void)
+{
+ if (0 <= readyfd) {
+ char c = '\n';
+ write(readyfd, &c, 1);
+ close(readyfd);
+ readyfd = -1;
+ }
+}
+
__dead void
usage(void)
{
@@ -176,7 +289,10 @@
/* NOTREACHED */
}
- conffile = CONFFILE;
+ if (access(CONFFILE, F_OK) < 0 && access(DEFAULTCONFFILE, F_OK) == 0)
+ conffile = DEFAULTCONFFILE;
+ else
+ conffile = CONFFILE;
memset(&lconf, 0, sizeof(lconf));
@@ -222,6 +338,12 @@
}
}
+ if (getenv("READYFD")) {
+ readyfd = atoi(getenv("READYFD"));
+ unsetenv("READYENV");
+ fcntl(readyfd, F_SETFD, O_CLOEXEC | O_CLOFORK);
+ }
+
/* log to stderr until daemonized */
logdest = LOG_TO_STDERR;
if (!lconf.debug)
@@ -335,6 +457,10 @@
if (pledge("stdio rpath inet settime proc exec id", NULL) == -1)
err(1, "pledge");
+ if (!lconf.settime) {
+ ready();
+ }
+
while (quit == 0) {
new_cnt = PFD_MAX + constraint_cnt;
if (new_cnt > pfd_elms) {
@@ -380,6 +506,7 @@
fatal("daemon");
writepid(&lconf);
}
+ ready();
}
if (nfds > 0 && (pfd[PFD_PIPE].revents & POLLOUT))
@@ -487,6 +614,7 @@
}
lconf->settime = 0;
timeout = INFTIM;
+ ready();
break;
case IMSG_CONSTRAINT_QUERY:
priv_constraint_msg(imsg.hdr.peerid,
@@ -507,9 +635,8 @@
void
reset_adjtime(void)
{
- struct timeval tv;
+ struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
- timerclear(&tv);
if (adjtime(&tv, NULL) == -1)
log_warn("reset adjtime failed");
}
@@ -523,9 +650,9 @@
d += getoffset();
if (d >= threshold || d <= -1 * threshold)
- log_info("adjusting local clock by %fs", d);
+ log_info("adjusting local clock by %llims", (long long)(d * 1000));
else
- log_debug("adjusting local clock by %fs", d);
+ log_debug("adjusting local clock by %llims", (long long)(d * 1000));
#ifdef HAVE_ADJTIMEX
int rc;
@@ -614,14 +741,26 @@
curtime.tv_sec += tv.tv_sec - 1 + (curtime.tv_usec / 1000000);
curtime.tv_usec %= 1000000;
+#if defined(__sortix__)
+ struct timespec ts =
+ {
+ .tv_sec = curtime.tv_sec,
+ .tv_nsec = curtime.tv_usec * 1000
+ };
+ if (clock_settime(CLOCK_REALTIME, &ts) == -1) {
+ log_warn("settimeofday");
+ return;
+ }
+#else
if (settimeofday(&curtime, NULL) == -1) {
log_warn("settimeofday");
return;
}
+#endif
tval = curtime.tv_sec;
strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y",
localtime(&tval));
- log_info("set local clock to %s (offset %fs)", buf, d);
+ log_info("set local clock to %s (offset %llims)", buf, (long long)(d * 1000.0));
}
static FILE *freqfp;
@@ -632,6 +771,7 @@
int64_t current;
int fd;
double d;
+ long long lli;
fd = open(DRIFTFILE, O_RDWR);
if (fd == -1) {
@@ -649,7 +789,8 @@
if (adjfreq(NULL, &current) == -1)
log_warn("adjfreq failed");
else if (current == 0 && freqfp) {
- if (fscanf(freqfp, "%lf", &d) == 1) {
+ if (fscanf(freqfp, "%lli", &lli) == 1) {
+ d = (double)lli;
d /= 1e6; /* scale from ppm */
ntpd_adjfreq(d, 0);
} else
@@ -667,7 +808,8 @@
if (freqfp == NULL)
return 0;
rewind(freqfp);
- r = fprintf(freqfp, "%.3f\n", d * 1e6); /* scale to ppm */
+ long long lli = (long long)(d * 1e6);
+ r = fprintf(freqfp, "%lli\n", lli); /* scale to ppm */
if (r < 0 || fflush(freqfp) != 0) {
if (warnonce) {
log_warnx("can't write %s", DRIFTFILE);
diff -Paur --no-dereference -- ntpd.upstream/src/ntpd.h ntpd/src/ntpd.h
--- ntpd.upstream/src/ntpd.h
+++ ntpd/src/ntpd.h
@@ -23,7 +23,9 @@
#include <sys/queue.h>
#include <sys/time.h>
#include <netinet/in.h>
+#if __has_include(<netinet/ip.h>)
#include <netinet/ip.h>
+#endif
#include <arpa/inet.h>
#include <netdb.h>
#include <pwd.h>
@@ -31,6 +33,11 @@
#include <poll.h>
#include <imsg.h>
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+
#include "ntp.h"
#include "log.h"
@@ -44,6 +51,7 @@
#define SYSCONFDIR "/etc"
#endif
#define CONFFILE SYSCONFDIR "/ntpd.conf"
+#define DEFAULTCONFFILE SYSCONFDIR "/default/ntpd.conf"
#ifndef LOCALSTATEDIR
#define LOCALSTATEDIR "/var"
diff -Paur --no-dereference -- ntpd.upstream/src/ntp_dns.c ntpd/src/ntp_dns.c
--- ntpd.upstream/src/ntp_dns.c
+++ ntpd/src/ntp_dns.c
@@ -20,8 +20,10 @@
#include <sys/resource.h>
#include <sys/time.h>
#include <netinet/in.h>
+#ifndef __sortix__
#include <arpa/nameser.h>
#include <resolv.h>
+#endif
#include <netinet/in.h>
@@ -33,11 +35,17 @@
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
+#ifndef __sortix__
#include <resolv.h>
+#endif
#include <unistd.h>
#include "ntpd.h"
+#ifdef __sortix__
+#define setgroups(a, b) ((void) (a), (void) (b), 0)
+#endif
+
volatile sig_atomic_t quit_dns = 0;
static struct imsgbuf *ibuf_dns;
extern int non_numeric;
@@ -64,7 +72,9 @@
struct pollfd pfd[1];
int nfds, nullfd;
+#ifndef __sortix__
res_init();
+#endif
if (setpriority(PRIO_PROCESS, 0, 0) == -1)
log_warn("could not set priority");
@@ -214,6 +224,9 @@
return (0);
}
+/* PATCH: Sortix doesn't have res_qury but it's only used to check if the DNS
+ is online, but init(8) already ensures that's the case. */
+#ifndef __sortix__
int
probe_root_ns(void)
{
@@ -238,18 +251,21 @@
return ret;
}
+#endif
void
probe_root(void)
{
int n;
+#ifndef __sortix__
n = probe_root_ns();
if (n < 0) {
/* give programs like unwind a second chance */
sleep(1);
n = probe_root_ns();
}
+#endif
if (imsg_compose(ibuf_dns, IMSG_PROBE_ROOT, 0, 0, -1, &n,
sizeof(int)) == -1)
fatalx("probe_root");
diff -Paur --no-dereference -- ntpd.upstream/src/ntp_msg.c ntpd/src/ntp_msg.c
--- ntpd.upstream/src/ntp_msg.c
+++ ntpd/src/ntp_msg.c
@@ -53,7 +53,11 @@
n = sendto(fd, msg, sizeof(*msg), 0, sa, sa_len);
if (n == -1) {
if (errno == ENOBUFS || errno == EHOSTUNREACH ||
- errno == ENETDOWN || errno == EHOSTDOWN) {
+ errno == ENETDOWN
+#ifdef EHOSTDOWN
+ || errno == EHOSTDOWN
+#endif
+ ) {
/* logging is futile */
return (-1);
}
diff -Paur --no-dereference -- ntpd.upstream/src/server.c ntpd/src/server.c
--- ntpd.upstream/src/server.c
+++ ntpd/src/server.c
@@ -41,7 +41,9 @@
u_int8_t *a6;
size_t sa6len = sizeof(struct in6_addr);
u_int new_cnt = 0;
+#ifdef IPTOS_LOWDELAY
int tos = IPTOS_LOWDELAY;
+#endif
#ifdef IPV6_V6ONLY
int on = 1;
#endif
@@ -109,12 +111,20 @@
case AF_INET:
if (((struct sockaddr_in *)&la->sa)->sin_port == 0)
((struct sockaddr_in *)&la->sa)->sin_port =
+#if defined(__sortix__)
+ 123;
+#else
se->s_port;
+#endif
break;
case AF_INET6:
if (((struct sockaddr_in6 *)&la->sa)->sin6_port == 0)
((struct sockaddr_in6 *)&la->sa)->sin6_port =
+#if defined(__sortix__)
+ 123;
+#else
se->s_port;
+#endif
break;
case AF_UNSPEC:
nla = TAILQ_NEXT(la, entry);
@@ -133,9 +143,11 @@
if ((la->fd = socket(la->sa.ss_family, SOCK_DGRAM, 0)) == -1)
fatal("socket");
+#ifdef IPTOS_LOWDELAY
if (la->sa.ss_family == AF_INET && setsockopt(la->fd,
IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == -1)
log_warn("setsockopt IPTOS_LOWDELAY");
+#endif
#ifdef IPV6_V6ONLY
if (la->sa.ss_family == AF_INET6 && setsockopt(la->fd,
@@ -183,7 +195,10 @@
fsa_len = sizeof(fsa);
if ((size = recvfrom(fd, &buf, sizeof(buf), 0,
(struct sockaddr *)&fsa, &fsa_len)) == -1) {
- if (errno == EHOSTUNREACH || errno == EHOSTDOWN ||
+ if (errno == EHOSTUNREACH ||
+#ifdef EHOSTDOWN
+ errno == EHOSTDOWN ||
+#endif
errno == ENETUNREACH || errno == ENETDOWN) {
log_warn("recvfrom %s",
log_sockaddr((struct sockaddr *)&fsa));
diff -Paur --no-dereference -- ntpd.upstream/src/util.c ntpd/src/util.c
--- ntpd.upstream/src/util.c
+++ ntpd/src/util.c
@@ -25,6 +25,8 @@
#include "ntpd.h"
+int adjtime(const struct timeval *delta, struct timeval *olddelta);
+
double
gettime_corrected(void)
{
diff -Paur --no-dereference -- ntpd.upstream/TODO.sortix ntpd/TODO.sortix
--- ntpd.upstream/TODO.sortix
+++ ntpd/TODO.sortix
@@ -0,0 +1,5 @@
+- nptd is unaware of leap seconds but Sortix is aware of them to the clock doesn't actually get synced correctly.
+- Sortix needs `adjtime` or the time adjustments can be jarring.
+- Sortix needs `strptime`.
+- Sortix needs `getservbyname` but worked around by hard-coding the ntp port.
+- The dns process wasn't being properly killed and awaited when exiting.

13
ports/ntpd/ntpd.port Normal file
View File

@ -0,0 +1,13 @@
NAME=ntpd
BUILD_LIBRARIES=libssl?
VERSION=6.8p1
DISTNAME=openntpd-$VERSION
COMPRESSION=tar.gz
ARCHIVE=$DISTNAME.$COMPRESSION
SHA256SUM=8582db838a399153d4a17f2a76518b638cc3020f58028575bf54127518f55a46
UPSTREAM_SITE=https://ftp.openbsd.org/pub/OpenBSD/OpenNTPD
UPSTREAM_ARCHIVE=$ARCHIVE
BUILD_SYSTEM=configure
MAKE_VARS='V=1'
POST_INSTALL=tix-eradicate-libtool-la
VERSION_REGEX='([0-9]+\.[0-9]+p[0-9]+)'

1
ports/ntpd/ntpd.rmpatch Normal file
View File

@ -0,0 +1 @@
rm -rf -- 'src/parse.c'

View File

@ -180,8 +180,9 @@ The system provides a default implementation that does nothing, as the base
system does not contain a daemon that obtains the current date and time.
The system administrator is meant to override the daemon in
.Pa /etc/init/time
by depending on a daemon that obtains the current date and time and sets the
system time.
by depending on a daemon such as
.Xr ntpd 8
that obtains the current date and time and sets the system time.
Daemons can depend on this daemon if they need the current date and time to have
been established before they start.
.El

View File

@ -385,6 +385,22 @@ and
.Pp
Please note that Sortix is not currently secure as a multi-user system and
filesystem permissions are not enforced.
.Ss Network Time
You will be asked if you want to enable the Network Time Protocol client
.Xr ntpd 8 ,
which will automatically synchronize the current time with the internet.
Although it's recommended to use network time to avoid clock drift, it does come
with potential privacy implications.
.Pp
Privacy notice: If enabled, the default configuration will obtain time from
various internet servers and the installer will inform you which ones they are.
You are encouraged to answer
.Sy man
to read the
.Xr ntpd.conf 5
manual and then answer
.Sy edit
to edit the configuration with your preferences.
.Ss SSH Server
You will be asked if you want to enable a
.Xr sshd 8

View File

@ -274,6 +274,11 @@ command line parameter that controls whether network drivers are enabled.
Either set to the empty string (network drivers are enabled) or
.Sy --disable-network-drivers .
(Default: The empty string).
.It Sy enable_ntpd
Whether to start the
.Xr ntpd 8
daemon.
(Default: false)
.It Sy enable_src
Whether to load the source code initrd containing
.Pa /src .

View File

@ -1199,6 +1199,65 @@ int main(void)
// TODO: Ask if networking should be disabled / enabled.
if ( !access_or_die("/tix/tixinfo/ntpd", F_OK) )
{
text("A Network Time Protocol client (ntpd) has been installed that "
"can automatically synchronize the current time with the internet."
"\n\n");
text("Privacy notice: If enabled, the default configuration will "
"obtain time from pool.ntp.org and time.cloudflare.com; and "
"compare with HTTPS timestamps from quad9 and www.google.com. "
"You are encouraged to edit /etc/ntpd.conf per the ntpd.conf(5) "
"manual with your preferences.\n\n");
bool copied = false;
while ( true )
{
prompt(input, sizeof(input), "enable_ntpd",
"Automatically get time from the network? (yes/no/edit/man)",
copied ? "yes" : "no");
if ( strcasecmp(input, "no") == 0 )
break;
if ( strcasecmp(input, "man") == 0 )
{
execute((const char*[]) {"man", "5", "ntpd.conf", NULL}, "fi");
continue;
}
if ( strcasecmp(input, "edit") == 0 )
{
if ( !copied )
{
execute((const char*[]) {"cp", "etc/default/ntpd.conf",
"etc/ntpd.conf", NULL}, "f");
copied = true;
}
const char* editor =
getenv("EDITOR") ? getenv("EDITOR") : "editor";
execute((const char*[]) {editor, "etc/ntpd.conf", NULL}, "f");
text("Created /etc/ntpd.conf from /etc/default/ntpd.conf\n");
continue;
}
if ( strcasecmp(input, "yes") != 0 )
continue;
if ( !install_configurationf("etc/init/local", "a",
"require ntpd optional\n") )
{
warn("etc/init/local");
continue;
}
if ( !install_configurationf("etc/init/time", "a",
"furthermore\n"
"require ntpd optional\n") )
{
warn("etc/init/time");
continue;
}
text("Added 'require ntpd optional' to /etc/init/local\n");
text("Added 'require ntpd optional' to /etc/init/time\n");
break;
}
text("\n");
}
struct sshd_key_file
{
const char* pri;

View File

@ -1,5 +1,5 @@
#!/bin/sh
# Copyright (c) 2017, 2018, 2022 Jonas 'Sortie' Termansen.
# Copyright (c) 2017, 2018, 2022, 2023 Jonas 'Sortie' Termansen.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@ -24,6 +24,7 @@ directory=
enable_append_title=true
enable_dhclient=
enable_network_drivers=
enable_ntpd=
enable_src=
enable_sshd=
init_target=
@ -56,11 +57,13 @@ for argument do
--disable-append-title) enable_append_title=false ;;
--disable-dhclient) enable_dhclient=false ;;
--disable-network-drivers) enable_network_drivers=false ;;
--disable-ntpd) enable_ntpd=false ;;
--disable-src) enable_src=false ;;
--disable-sshd) enable_sshd=false ;;
--enable-append-title) enable_append_title=true ;;
--enable-dhclient) enable_dhclient=true ;;
--enable-network-drivers) enable_network_drivers=true ;;
--enable-ntpd) enable_ntpd=true ;;
--enable-src) enable_src=true ;;
--enable-sshd) enable_sshd=true ;;
--init-target=*) init_target=$parameter ;;
@ -148,6 +151,7 @@ mkdir -p -- "$directory/boot/grub"
print_enable_default "$enable_network_drivers" network_drivers network-drivers
print_enable_default_bool "$enable_src" src src
print_enable_default_bool "$enable_sshd" sshd sshd
print_enable_default_bool "$enable_ntpd" ntpd ntpd
if $enable_append_title; then
printf "base_menu_title=\"\$base_menu_title - \"'%s'\n" \
"$(printf '%s\n' "$append_title" | sed "s/'/'\\\\''/g")"

View File

@ -11,11 +11,13 @@
.Op Fl \-disable-append-title
.Op Fl \-disable-dhclient
.Op Fl \-disable-network-drivers
.Op Fl \-disable-ntpd
.Op Fl \-disable-src
.Op Fl \-disable-sshd
.Op Fl \-enable-append-title
.Op Fl \-enable-dhclient
.Op Fl \-enable-network-drivers
.Op Fl \-enable-ntpd
.Op Fl \-enable-src
.Op Fl \-enable-sshd
.Op Fl \-init-target Ns = Ns Ar target
@ -111,6 +113,14 @@ GRUB variable to the
option which will be passed on the
.Xr kernel 7
command line.
.It Fl \-disable-ntpd
Disable automatically starting the ntp client by setting the
.Sy enable_ntpd
GRUB variable to
.Sy false ,
selecting the default behavior of not starting the
.Xr ntpd 8
daemon.
.It Fl \-disable-src
Disable loading the source code in
.Pa /src
@ -150,6 +160,14 @@ GRUB variable to the
option which will be passed on the
.Xr kernel 7
command line.
.It Fl \-enable-ntpd
Enable automatically starting the ntp client by setting the
.Sy enable_ntpd
GRUB variable to
.Sy true ,
causing the bootloader to load additional configuration that turns on the
.Xr ntpd 8
daemon on boot.
.It Fl \-enable-src
Enable loading the source code in
.Pa /src