aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.config1
-rw-r--r--generated/config.h2
-rw-r--r--generated/flags.h14
-rw-r--r--generated/globals.h7
-rw-r--r--generated/help.h2
-rw-r--r--generated/newtoys.h1
-rw-r--r--kconfig/freebsd_miniconfig128
-rw-r--r--lib/lib.h1
-rw-r--r--lib/net.c22
-rwxr-xr-xscripts/install.sh2
-rwxr-xr-xtests/cp.test7
-rw-r--r--toys/net/ping.c9
-rw-r--r--toys/pending/sntp.c65
-rw-r--r--toys/posix/cp.c2
-rw-r--r--toys/posix/patch.c26
15 files changed, 258 insertions, 31 deletions
diff --git a/.config b/.config
index c3bf7712..f224a981 100644
--- a/.config
+++ b/.config
@@ -272,6 +272,7 @@ CONFIG_SHA512SUM=y
# CONFIG_SKELETON is not set
CONFIG_SLEEP_FLOAT=y
CONFIG_SLEEP=y
+# CONFIG_SNTP is not set
CONFIG_SORT_BIG=y
CONFIG_SORT_FLOAT=y
CONFIG_SORT=y
diff --git a/generated/config.h b/generated/config.h
index b5cc9653..e39e17d4 100644
--- a/generated/config.h
+++ b/generated/config.h
@@ -518,6 +518,8 @@
#define USE_SLEEP_FLOAT(...) __VA_ARGS__
#define CFG_SLEEP 1
#define USE_SLEEP(...) __VA_ARGS__
+#define CFG_SNTP 0
+#define USE_SNTP(...)
#define CFG_SORT_BIG 1
#define USE_SORT_BIG(...) __VA_ARGS__
#define CFG_SORT_FLOAT 1
diff --git a/generated/flags.h b/generated/flags.h
index 34c31ccd..09b34213 100644
--- a/generated/flags.h
+++ b/generated/flags.h
@@ -2486,6 +2486,14 @@
#undef FOR_sleep
#endif
+// sntp <1
+#undef OPTSTR_sntp
+#define OPTSTR_sntp "<1"
+#ifdef CLEANUP_sntp
+#undef CLEANUP_sntp
+#undef FOR_sntp
+#endif
+
// sort gS:T:mo:k*t:xVbMcszdfirun gS:T:mo:k*t:xVbMcszdfirun
#undef OPTSTR_sort
#define OPTSTR_sort "gS:T:mo:k*t:xVbMcszdfirun"
@@ -5373,6 +5381,12 @@
#endif
#endif
+#ifdef FOR_sntp
+#ifndef TT
+#define TT this.sntp
+#endif
+#endif
+
#ifdef FOR_sort
#ifndef TT
#define TT this.sort
diff --git a/generated/globals.h b/generated/globals.h
index dd3ce2bc..1ac1a5a4 100644
--- a/generated/globals.h
+++ b/generated/globals.h
@@ -761,6 +761,12 @@ struct sh_data {
long lineno;
};
+// toys/pending/sntp.c
+
+struct sntp_data {
+ int unused;
+};
+
// toys/pending/stty.c
struct stty_data {
@@ -1415,6 +1421,7 @@ extern union global_union {
struct openvt_data openvt;
struct route_data route;
struct sh_data sh;
+ struct sntp_data sntp;
struct stty_data stty;
struct sulogin_data sulogin;
struct syslogd_data syslogd;
diff --git a/generated/help.h b/generated/help.h
index 692a1d4a..472ee2ec 100644
--- a/generated/help.h
+++ b/generated/help.h
@@ -340,6 +340,8 @@
#define HELP_stty "usage: stty [-ag] [-F device] SETTING...\n\nGet/set terminal configuration.\n\n-F Open device instead of stdin\n-a Show all current settings (default differences from \"sane\")\n-g Show all current settings usable as input to stty\n\nSpecial characters (syntax ^c or undef): intr quit erase kill eof eol eol2\nswtch start stop susp rprnt werase lnext discard\n\nControl/input/output/local settings as shown by -a, '-' prefix to disable\n\nCombo settings: cooked/raw, evenp/oddp/parity, nl, ek, sane\n\nN set input and output speed (ispeed N or ospeed N for just one)\ncols N set number of columns\nrows N set number of rows\nline N set line discipline\nmin N set minimum chars per read\ntime N set read timeout\nspeed show speed only\nsize show size only\n\n"
+#define HELP_sntp "usage: sntp SERVER...\n\nSimple Network Time Protocol client, set system clock from a server.\n\n"
+
#define HELP_exit "usage: exit [status]\n\nExit shell. If no return value supplied on command line, use value\nof most recent command, or 0 if none.\n\n"
#define HELP_cd "usage: cd [-PL] [path]\n\nChange current directory. With no arguments, go $HOME.\n\n-P Physical path: resolve symlinks in path\n-L Local path: .. trims directories off $PWD (default)\n\n"
diff --git a/generated/newtoys.h b/generated/newtoys.h
index ed8e004f..772b8c1f 100644
--- a/generated/newtoys.h
+++ b/generated/newtoys.h
@@ -225,6 +225,7 @@ USE_SHRED(NEWTOY(shred, "<1zxus#<1n#<1o#<0f", TOYFLAG_USR|TOYFLAG_BIN))
USE_SKELETON(NEWTOY(skeleton, "(walrus)(blubber):;(also):e@d*c#b:a", TOYFLAG_USR|TOYFLAG_BIN))
USE_SKELETON_ALIAS(NEWTOY(skeleton_alias, "b#dq", TOYFLAG_USR|TOYFLAG_BIN))
USE_SLEEP(NEWTOY(sleep, "<1", TOYFLAG_BIN))
+USE_SNTP(NEWTOY(sntp, "<1", TOYFLAG_USR|TOYFLAG_BIN))
USE_SORT(NEWTOY(sort, USE_SORT_FLOAT("g")"S:T:m" "o:k*t:" "xVbMcszdfirun", TOYFLAG_USR|TOYFLAG_BIN))
USE_SPLIT(NEWTOY(split, ">2a#<1=2>9b#<1l#<1[!bl]", TOYFLAG_USR|TOYFLAG_BIN))
USE_START(NEWTOY(start, "", TOYFLAG_USR|TOYFLAG_SBIN))
diff --git a/kconfig/freebsd_miniconfig b/kconfig/freebsd_miniconfig
new file mode 100644
index 00000000..98d3c1cd
--- /dev/null
+++ b/kconfig/freebsd_miniconfig
@@ -0,0 +1,128 @@
+CONFIG_BASENAME=y
+CONFIG_CAL=y
+CONFIG_CAT=y
+CONFIG_CATV=y
+CONFIG_CHGRP=y
+CONFIG_CHOWN=y
+CONFIG_CHMOD=y
+CONFIG_CKSUM=y
+CONFIG_CRC32=y
+CONFIG_CMP=y
+CONFIG_COMM=y
+CONFIG_CPIO=y
+CONFIG_CUT=y
+CONFIG_DATE=y
+CONFIG_DIRNAME=y
+CONFIG_DU=y
+CONFIG_ECHO=y
+CONFIG_EXPAND=y
+CONFIG_FALSE=y
+CONFIG_FILE=y
+CONFIG_FIND=y
+CONFIG_GREP=y
+CONFIG_HEAD=y
+CONFIG_ICONV=y
+CONFIG_ID=y
+CONFIG_GROUPS=y
+CONFIG_LOGNAME=y
+CONFIG_WHOAMI=y
+CONFIG_KILL=y
+CONFIG_KILLALL5=y
+CONFIG_LINK=y
+CONFIG_LN=y
+CONFIG_LOGGER=y
+CONFIG_LS=y
+CONFIG_MKDIR=y
+CONFIG_MKFIFO=y
+CONFIG_NICE=y
+CONFIG_NL=y
+CONFIG_NOHUP=y
+CONFIG_OD=y
+CONFIG_PASTE=y
+CONFIG_PATCH=y
+CONFIG_PRINTF=y
+CONFIG_PWD=y
+CONFIG_RENICE=y
+CONFIG_RM=y
+CONFIG_RMDIR=y
+CONFIG_SED=y
+CONFIG_SLEEP=y
+CONFIG_SORT=y
+CONFIG_SPLIT=y
+CONFIG_STRINGS=y
+CONFIG_TEE=y
+CONFIG_TEST=y
+CONFIG_TIME=y
+CONFIG_TOUCH=y
+CONFIG_TRUE=y
+CONFIG_TTY=y
+CONFIG_UNAME=y
+CONFIG_UNIQ=y
+CONFIG_UNLINK=y
+CONFIG_UUDECODE=y
+CONFIG_UUENCODE=y
+CONFIG_WC=y
+CONFIG_WHO=y
+CONFIG_XARGS=y
+CONFIG_ACPI=y
+CONFIG_ASCII=y
+CONFIG_BASE64=y
+CONFIG_BUNZIP2=y
+CONFIG_BZCAT=y
+CONFIG_CHROOT=y
+CONFIG_CHRT=y
+CONFIG_CHVT=y
+CONFIG_CLEAR=y
+CONFIG_COUNT=y
+CONFIG_DOS2UNIX=y
+CONFIG_UNIX2DOS=y
+CONFIG_FACTOR=y
+CONFIG_FALLOCATE=y
+CONFIG_FLOCK=y
+CONFIG_FMT=y
+CONFIG_FSYNC=y
+CONFIG_HELP=y
+CONFIG_HELP_EXTRAS=y
+CONFIG_HEXEDIT=y
+CONFIG_LSMOD=y
+CONFIG_LSPCI=y
+CONFIG_LSPCI_TEXT=y
+CONFIG_LSUSB=y
+CONFIG_MAKEDEVS=y
+CONFIG_MKPASSWD=y
+CONFIG_MKSWAP=y
+CONFIG_MODINFO=y
+CONFIG_MOUNTPOINT=y
+CONFIG_PMAP=y
+CONFIG_PRINTENV=y
+CONFIG_PWDX=y
+CONFIG_READLINK=y
+CONFIG_REALPATH=y
+CONFIG_RESET=y
+CONFIG_REV=y
+CONFIG_SETSID=y
+CONFIG_SHRED=y
+CONFIG_SYSCTL=y
+CONFIG_TAC=y
+CONFIG_TIMEOUT=y
+CONFIG_TRUNCATE=y
+CONFIG_USLEEP=y
+CONFIG_UUIDGEN=y
+CONFIG_VMSTAT=y
+CONFIG_WATCH=y
+CONFIG_W=y
+CONFIG_WHICH=y
+CONFIG_XXD=y
+CONFIG_YES=y
+CONFIG_HOSTNAME=y
+CONFIG_KILLALL=y
+CONFIG_MKNOD=y
+CONFIG_MKTEMP=y
+CONFIG_PIDOF=y
+CONFIG_SEQ=y
+CONFIG_SYNC=y
+CONFIG_TOYBOX_SUID=y
+CONFIG_TOYBOX_FLOAT=y
+CONFIG_TOYBOX_HELP=y
+CONFIG_TOYBOX_HELP_DASHDASH=y
+CONFIG_TOYBOX_I18N=y
diff --git a/lib/lib.h b/lib/lib.h
index 578a99c9..546b32b3 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -310,6 +310,7 @@ int xbind(struct addrinfo *ai);
int xpoll(struct pollfd *fds, int nfds, int timeout);
int pollinate(int in1, int in2, int out1, int out2, int timeout, int shutdown_timeout);
char *ntop(struct sockaddr *sa);
+void xsendto(int sockfd, void *buf, size_t len, struct sockaddr *dest);
// password.c
int get_salt(char *salt, char * algo);
diff --git a/lib/net.c b/lib/net.c
index 136536fe..346d17e9 100644
--- a/lib/net.c
+++ b/lib/net.c
@@ -67,13 +67,16 @@ int xbind(struct addrinfo *ai)
int xpoll(struct pollfd *fds, int nfds, int timeout)
{
int i;
+ long long now, then = timeout>0 ? millitime() : 0;
for (;;) {
- if (0>(i = poll(fds, nfds, timeout))) {
- if (toys.signal) return i;
- if (errno != EINTR && errno != ENOMEM) perror_exit("xpoll");
- else if (timeout>0) timeout--;
- } else return i;
+ if (0<=(i = poll(fds, nfds, timeout)) || toys.signal) return i;
+ if (errno != EINTR && errno != ENOMEM) perror_exit("xpoll");
+ else {
+ now = millitime();
+ timeout -= now-then;
+ then = now;
+ }
}
}
@@ -126,3 +129,12 @@ char *ntop(struct sockaddr *sa)
return libbuf;
}
+
+void xsendto(int sockfd, void *buf, size_t len, struct sockaddr *dest)
+{
+ int rc = sendto(sockfd, buf, len, 0, dest,
+ dest->sa_family == AF_INET ? sizeof(struct sockaddr_in) :
+ sizeof(struct sockaddr_in6));
+
+ if (rc != len) perror_exit("sendto");
+}
diff --git a/scripts/install.sh b/scripts/install.sh
index b780ef4b..96d5bbdf 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -106,7 +106,7 @@ done
# The following are commands toybox should provide, but doesn't yet.
# For now symlink the host version. This list must go away by 1.0.
-PENDING="bunzip2 bzcat dd diff expr ftpd ftpget ftpput gunzip less route tar test tr vi wget zcat awk bzip2 fdisk gzip sh sha512sum unxz xzcat bc bison flex"
+PENDING="bunzip2 bzcat dd diff expr ftpd ftpget ftpput gunzip less route tar tr vi wget zcat awk bzip2 fdisk gzip sh sha512sum sha256sum unxz xzcat bc bison flex"
# "gcc" should go away for llvm, but some things still hardwire it
TOOLCHAIN="ar as nm cc make ld gcc objdump"
diff --git a/tests/cp.test b/tests/cp.test
index 2b89e2f2..a720d1f5 100755
--- a/tests/cp.test
+++ b/tests/cp.test
@@ -89,6 +89,13 @@ testing "-r dir1/* dir2" \
"cp -r one/* dir2 && diff -r one dir2 && echo yes" "yes\n" "" ""
rm -rf one dir dir2
+touch walrus
+chmod 644 walrus
+ln -s walrus woot
+
+testing "symlink dest permissions" "cp woot carpenter && stat -c %A carpenter" \
+ "-rw-r--r--\n" "" ""
+
# cp -r ../source destdir
# cp -r one/two/three missing
# cp -r one/two/three two
diff --git a/toys/net/ping.c b/toys/net/ping.c
index 1829af71..bc3381d8 100644
--- a/toys/net/ping.c
+++ b/toys/net/ping.c
@@ -55,15 +55,6 @@ GLOBALS(
unsigned long sent, recv, fugit, min, max;
)
-static void xsendto(int sockfd, void *buf, size_t len, struct sockaddr *dest)
-{
- int rc = sendto(TT.sock, buf, len, 0, dest,
- dest->sa_family == AF_INET ? sizeof(struct sockaddr_in) :
- sizeof(struct sockaddr_in6));
-
- if (rc != len) perror_exit("sendto");
-}
-
static void summary(int sig)
{
if (!(toys.optflags&FLAG_q) && TT.sent && TT.sa) {
diff --git a/toys/pending/sntp.c b/toys/pending/sntp.c
new file mode 100644
index 00000000..f34c3da2
--- /dev/null
+++ b/toys/pending/sntp.c
@@ -0,0 +1,65 @@
+/* sntp.c - sntp client and server
+ *
+ * Copyright 2019 Rob Landley <rob@landley.net>
+ *
+ * See https://www.ietf.org/rfc/rfc4330.txt
+
+USE_SNTP(NEWTOY(sntp, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+
+config SNTP
+ bool "sntp"
+ default n
+ help
+ usage: sntp SERVER...
+
+ Simple Network Time Protocol client, set system clock from a server.
+*/
+
+#define FOR_sntp
+#include "toys.h"
+
+GLOBALS(
+ int unused;
+)
+
+union socksaddr {
+ struct sockaddr_in in;
+ struct sockaddr_in6 in6;
+};
+
+// timeout in milliseconds
+int xrecvwait(int fd, char *buf, int len, union socksaddr *sa, int timeout)
+{
+ socklen_t sl = sizeof(*sa);
+
+ if (timeout >= 0) {
+ struct pollfd pfd;
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ if (!xpoll(&pfd, 1, timeout)) return 0;
+ }
+
+ len = recvfrom(fd, buf, len, 0, (void *)sa, &sl);
+ if (len<0) perror_exit("recvfrom");
+
+ return len;
+}
+
+void sntp_main(void)
+{
+ struct addrinfo *ai;
+ union socksaddr sa;
+ int fd, len;
+
+ ai = xgetaddrinfo(*toys.optargs, 0, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, 0);
+ // When root, bind to local server address
+ if (!getuid())
+ fd = xbind(xgetaddrinfo("", "123", AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, 0));
+ else fd = xsocket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP);
+
+ xsendto(fd, toybuf, 48, ai->ai_addr);
+ len = xrecvwait(fd, toybuf, sizeof(toybuf), &sa, 5000);
+ printf("%d\n", len);
+ if (len>0) write(1, toybuf, len);
+}
diff --git a/toys/posix/cp.c b/toys/posix/cp.c
index da658319..5e1a0163 100644
--- a/toys/posix/cp.c
+++ b/toys/posix/cp.c
@@ -268,6 +268,8 @@ static int cp_node(struct dirtree *try)
catch = try->name;
break;
}
+ // When copying contents use symlink target's attributes
+ if (S_ISLNK(try->st.st_mode)) fstat(fdin, &try->st);
fdout = openat(cfd, catch, O_RDWR|O_CREAT|O_TRUNC, try->st.st_mode);
if (fdout >= 0) {
xsendfile(fdin, fdout);
diff --git a/toys/posix/patch.c b/toys/posix/patch.c
index f12f9183..efb15432 100644
--- a/toys/posix/patch.c
+++ b/toys/posix/patch.c
@@ -71,7 +71,7 @@ static void do_line(void *data)
struct double_list *dlist = (struct double_list *)data;
if (TT.state>1 && *dlist->data != TT.state) {
- char *s = dlist->data+(TT.state>3 ? 1 : 0);
+ char *s = dlist->data+(TT.state>3);
int i = TT.state == 2 ? 2 : TT.fileout;
xwrite(i, s, strlen(s));
@@ -104,8 +104,7 @@ static void fail_hunk(void)
TT.state = 2;
llist_traverse(TT.current_hunk, do_line);
TT.current_hunk = NULL;
- if (!FLAG(dry_run))
- delete_tempfile(TT.filein, TT.fileout, &TT.tempname);
+ if (!FLAG(dry_run)) delete_tempfile(TT.filein, TT.fileout, &TT.tempname);
TT.state = 0;
}
@@ -147,10 +146,9 @@ static int apply_one_hunk(void)
}
matcheof = !trailing || trailing < TT.context;
- if (FLAG(x))
- fprintf(stderr,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N');
+ if (FLAG(x)) fprintf(stderr,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N');
- // Loop through input data searching for this hunk. Match all context
+ // Loop through input data searching for this hunk. Match all context
// lines and all lines to be removed until we've found the end of a
// complete hunk.
plist = TT.current_hunk;
@@ -160,12 +158,11 @@ static int apply_one_hunk(void)
char *data = get_line(TT.filein);
TT.linenum++;
- // Figure out which line of hunk to compare with next. (Skip lines
+ // Figure out which line of hunk to compare with next. (Skip lines
// of the hunk we'd be adding.)
while (plist && *plist->data == "+-"[reverse]) {
- if (data && !lcmp(data, plist->data+1)) {
+ if (data && !lcmp(data, plist->data+1))
if (!backwarn) backwarn = TT.linenum;
- }
plist = plist->next;
}
@@ -227,7 +224,7 @@ static int apply_one_hunk(void)
check = buf;
} else {
if (FLAG(x)) fprintf(stderr, "MAYBE: %s\n", plist->data);
- // This line matches. Advance plist, detect successful match.
+ // This line matches. Advance plist, detect successful match.
plist = plist->next;
if (!plist && !matcheof) goto out;
check = check->next;
@@ -275,8 +272,7 @@ void patch_main(void)
patchline = get_line(TT.filepatch);
if (!patchline) break;
- // Other versions of patch accept damaged patches,
- // so we need to also.
+ // Other versions of patch accept damaged patches, so we need to also.
if (strip || !patchlinenum++) {
int len = strlen(patchline);
if (patchline[len-1] == '\r') {
@@ -303,7 +299,6 @@ void patch_main(void)
else state=3;
// If we've consumed all expected hunk lines, apply the hunk.
-
if (!TT.oldlen && !TT.newlen) state = apply_one_hunk();
continue;
}
@@ -327,7 +322,7 @@ void patch_main(void)
finish_oldfile();
// Trim date from end of filename (if any). We don't care.
- for (s = patchline+4; *s && *s!='\t'; s++)
+ for (s = patchline+4; *s && (*s!='\t' || !isdigit(s[1])); s++)
if (*s=='\\' && s[1]) s++;
i = atoi(s);
if (i>1900 && i<=1970) *name = xstrdup("/dev/null");
@@ -401,8 +396,7 @@ void patch_main(void)
if (!FLAG(s)) printf("patching %s\n", name);
TT.filein = xopenro(name);
}
- if (FLAG(dry_run))
- TT.fileout = xopen("/dev/null", O_RDWR);
+ if (FLAG(dry_run)) TT.fileout = xopen("/dev/null", O_RDWR);
else TT.fileout = copy_tempfile(TT.filein, name, &TT.tempname);
TT.linenum = 0;
TT.hunknum = 0;