diff options
-rw-r--r-- | .config | 1 | ||||
-rw-r--r-- | generated/config.h | 2 | ||||
-rw-r--r-- | generated/flags.h | 14 | ||||
-rw-r--r-- | generated/globals.h | 7 | ||||
-rw-r--r-- | generated/help.h | 2 | ||||
-rw-r--r-- | generated/newtoys.h | 1 | ||||
-rw-r--r-- | kconfig/freebsd_miniconfig | 128 | ||||
-rw-r--r-- | lib/lib.h | 1 | ||||
-rw-r--r-- | lib/net.c | 22 | ||||
-rwxr-xr-x | scripts/install.sh | 2 | ||||
-rwxr-xr-x | tests/cp.test | 7 | ||||
-rw-r--r-- | toys/net/ping.c | 9 | ||||
-rw-r--r-- | toys/pending/sntp.c | 65 | ||||
-rw-r--r-- | toys/posix/cp.c | 2 | ||||
-rw-r--r-- | toys/posix/patch.c | 26 |
15 files changed, 258 insertions, 31 deletions
@@ -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 @@ -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); @@ -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; |