Merge remote-tracking branch 'toybox/master' into HEAD
diff --git a/Makefile b/Makefile
index 2c9a857..d2919e7 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@
scripts/make.sh
.PHONY: clean distclean baseline bloatcheck install install_flat \
- uinstall uninstall_flat test tests help toybox_stuff
+ uinstall uninstall_flat test tests help toybox_stuff change
include kconfig/Makefile
@@ -46,14 +46,7 @@
scripts/install.sh --long --uninstall
change:
- @NOBUILD=1 scripts/make.sh > /dev/null&& \
- $(HOSTCC) -I . scripts/install.c -o generated/instlist && \
- export PREFIX=$${PREFIX:-change/} && \
- mkdir -p "$$PREFIX" && \
- for i in $$(generated/instlist); \
- do echo -n "$$i " && \
- scripts/single.sh $$i > /dev/null || touch $$PREFIX/$${i}.bad; \
- done
+ scripts/change.sh
clean::
rm -rf toybox toybox_unstripped generated change .singleconfig*
diff --git a/lib/lib.h b/lib/lib.h
index 621ed27..a659b69 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -128,6 +128,7 @@
long xparsetime(char *arg, long units, long *fraction);
void xpidfile(char *name);
void xregcomp(regex_t *preg, char *rexec, int cflags);
+char *xtzset(char *new);
// lib.c
void verror_msg(char *msg, int err, va_list va);
diff --git a/lib/xwrap.c b/lib/xwrap.c
index cd3c684..0a2b38f 100644
--- a/lib/xwrap.c
+++ b/lib/xwrap.c
@@ -627,3 +627,14 @@
error_exit("xregcomp: %s", libbuf);
}
}
+
+char *xtzset(char *new)
+{
+ char *tz = getenv("TZ");
+
+ if (tz) tz = xstrdup(tz);
+ if (setenv("TZ", new, 1)) perror_exit("setenv");
+ tzset();
+
+ return tz;
+}
diff --git a/main.c b/main.c
index 458d470..a81cfb9 100644
--- a/main.c
+++ b/main.c
@@ -127,15 +127,15 @@
{
struct toy_list *which;
- // don't blank old optargs if our new argc lives in the old optargs.
- if (argv>=toys.optargs && argv<=toys.optargs+toys.optc) toys.optargs = 0;
-
// Return if we can't find it, or need to re-exec to acquire root,
// or if stack depth is getting silly.
if (!(which = toy_find(argv[0]))) return;
if (toys.recursion && (which->flags & TOYFLAG_ROOTONLY) && getuid()) return;
if (toys.recursion++ > 5) return;
+ // don't blank old optargs if our new argc lives in the old optargs.
+ if (argv>=toys.optargs && argv<=toys.optargs+toys.optc) toys.optargs = 0;
+
// Run command
toy_init(which, argv);
if (toys.which) toys.which->toy_main();
diff --git a/scripts/change.sh b/scripts/change.sh
new file mode 100755
index 0000000..8b8ab92
--- /dev/null
+++ b/scripts/change.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# build each command as a standalone executable
+
+NOBUILD=1 scripts/make.sh > /dev/null &&
+${HOSTCC:-cc} -I . scripts/install.c -o generated/instlist &&
+export PREFIX=${PREFIX:-change/} &&
+mkdir -p "$PREFIX" || exit 1
+
+# Build all the commands standalone except:
+
+# sh - shell builtins like "cd" and "exit" need the multiplexer
+# help - needs to know what other commands are enabled (use command --help)
+
+for i in $(generated/instlist | egrep -vw "sh|help")
+do
+ echo -n "$i " &&
+ scripts/single.sh $i > /dev/null || touch $PREFIX/${i}.bad
+done
diff --git a/scripts/single.sh b/scripts/single.sh
index ce8695c..a151047 100755
--- a/scripts/single.sh
+++ b/scripts/single.sh
@@ -26,7 +26,7 @@
make allnoconfig > /dev/null &&
sed -ri -e "s/CONFIG_TOYBOX=y/# CONFIG_TOYBOX is not set/;t" \
- -e "s/# (CONFIG_(TOYBOX(|_HELP|_I18N|_FLOAT)|$NAME|${NAME}_.*${DEPENDS:+|$DEPENDS})) is not set/\1=y/" \
+ -e "s/# (CONFIG_(TOYBOX(|_HELP.*|_I18N|_FLOAT)|$NAME|${NAME}_.*${DEPENDS:+|$DEPENDS})) is not set/\1=y/" \
"$KCONFIG_CONFIG" &&
make &&
mv toybox $PREFIX$i || exit 1
diff --git a/tests/useradd.test b/tests/useradd.test
index a87da07..61d5e5d 100644
--- a/tests/useradd.test
+++ b/tests/useradd.test
@@ -5,8 +5,12 @@
[ -f testing.sh ] && . testing.sh
-# 70 characters long string; hereafter, we will use it as per our need.
-_s70="abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvwxyz123456789"
+if [ "$(id -u)" -ne 0 ]
+then
+ echo "SKIPPED: chgrp (not root)"
+ continue 2>/dev/null
+ exit
+fi
# Redirecting all output to /dev/null for grep, adduser and deluser
arg="&>/dev/null"
@@ -16,75 +20,85 @@
# Default password for adding user is: 'password'
pass=`echo -ne 'password\npassword\n'`
-testing "adduser user_name (text)" "useradd toyTestUser $arg ||
- grep '^toyTestUser:' /etc/passwd $arg && test -d /home/toyTestUser &&
- userdel toyTestUser $arg && rm -rf /home/toyTestUser && echo 'yes'" \
- "yes\n" "" "$pass"
+user="toyTestUser"
+testing "adduser user_name (text)" "useradd $user $arg ||
+ grep '^$user:' /etc/passwd $arg && [ -d /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
-testing "adduser user_name (alphanumeric)" "useradd toy1Test2User3 $arg ||
- grep '^toy1Test2User3:' /etc/passwd $arg && test -d /home/toy1Test2User3 &&
- userdel toy1Test2User3 $arg && rm -rf /home/toy1Test2User3 && echo 'yes'" \
- "yes\n" "" "$pass"
+user="toy1Test2User3"
+testing "adduser user_name (alphanumeric)" "useradd $user $arg ||
+ grep '^$user:' /etc/passwd $arg && [ -d /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
-testing "adduser user_name (numeric)" "useradd 987654321 $arg ||
- grep '^987654321:' /etc/passwd $arg && test -d /home/987654321 &&
- userdel 987654321 $arg && rm -rf /home/987654321 && echo 'yes'" \
- "yes\n" "" "$pass"
+user="987654321"
+testing "adduser user_name (numeric)" "useradd $user $arg ||
+ grep '^$user:' /etc/passwd $arg && [ -d /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
-testing "adduser user_name (with ./-/_)" "useradd toy.1Test-2User_3 $arg ||
- grep '^toy.1Test-2User_3:' /etc/passwd $arg &&
- test -d /home/toy.1Test-2User_3 && userdel toy.1Test-2User_3 $arg &&
- rm -rf /home/toy.1Test-2User_3 && echo 'yes'" "yes\n" "" "$pass"
+user="toy.1Test-2User_3"
+testing "adduser user_name (with ./-/_)" "useradd $user $arg ||
+ grep '^$user:' /etc/passwd $arg && [ -d /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
-testing "adduser user_name (long string)" "useradd $_s70 $arg ||
- grep '^$_s70:' /etc/passwd $arg && test -d /home/$_s70 &&
- userdel $_s70 $arg && rm -rf /home/$_s70 && echo 'yes'" "yes\n" "" "$pass"
+# 70 characters long string; hereafter, we will use it as per our need.
+user="abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvwxyz123456789"
+testing "adduser user_name (long string)" "useradd $user $arg ||
+ grep '^$user:' /etc/passwd $arg && [ -d /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
-testing "adduser user_name with dir" "useradd -h $PWD/dir toyTestUser $arg ||
- grep '^toyTestUser:.*dir' /etc/passwd $arg && test -d $PWD/dir &&
- userdel toyTestUser $arg && rm -rf $PWD/dir && echo 'yes'" "yes\n" "" "$pass"
+user="toyTestUser"
+testing "adduser user_name with dir" "useradd -h $PWD/dir $user $arg ||
+ grep '^$user:.*dir' /etc/passwd $arg && [ -d $PWD/dir ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
+rm -rf $PWD/dir
gecos="aaa,bbb,ccc,ddd,eee"
-testing "adduser user_name with gecos" "useradd -g '$gecos' toyTestUser $arg ||
- grep '^toyTestUser:.*$gecos' /etc/passwd $arg && test -d /home/toyTestUser &&
- userdel toyTestUser $arg && rm -rf /home/toyTestUser && echo 'yes'" \
- "yes\n" "" "$pass"
+testing "adduser user_name with gecos" "useradd -g '$gecos' $user $arg ||
+ grep '^$user:.*$gecos' /etc/passwd $arg && [ -d /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
shl="/bin/sh"
-testing "adduser user_name with shell" "useradd -s $shl toyTestUser $arg ||
- grep '^toyTestUser:.*$shl$' /etc/passwd $arg && test -d /home/toyTestUser &&
- userdel toyTestUser $arg && rm -rf /home/toyTestUser && echo 'yes'" \
- "yes\n" "" "$pass"
+testing "adduser user_name with shell" "useradd -s $shl $user $arg ||
+ grep '^$user:.*$shl$' /etc/passwd $arg && [ -d /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
g_name="root"
-g_id=`grep $g_name /etc/group | cut -d : -f 3`
-testing "adduser user_name with group" "useradd -G $g_name toyTestUser $arg ||
- grep '^toyTestUser:.*:.*:$g_id:.*' /etc/passwd $arg &&
- test -d /home/toyTestUser && userdel toyTestUser $arg &&
- rm -rf /home/toyTestUser && echo 'yes'" "yes\n" "" "$pass"
+g_id=`grep $g_name':.*:.*' /etc/group | cut -d : -f 3`
+testing "adduser user_name with group" "useradd -G $g_name $user $arg ||
+ grep '^$user:.*:.*:$g_id:.*' /etc/passwd $arg && [ -d /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
-testing "adduser user_name (system user)" "useradd -S toyTestUser $arg ||
- grep '^toyTestUser:.*:.*:.*' /etc/passwd $arg &&
- test ! -e /home/toyTestUser && userdel toyTestUser $arg && echo 'yes'" \
- "yes\n" "" "$pass"
+testing "adduser user_name (system user)" "useradd -S $user $arg ||
+ grep '^$user:.*:.*:.*' /etc/passwd $arg && [ ! -e /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
-testing "adduser user_name with -D" "useradd -D toyTestUser $arg ||
- grep '^toyTestUser:.*:.*:.*' /etc/passwd $arg && test -d /home/toyTestUser &&
- userdel toyTestUser $arg && rm -rf /home/toyTestUser && echo 'yes'" \
- "yes\n" "" "$pass"
+testing "adduser user_name with -D" "useradd -D $user $arg ||
+ grep '^$user:.*:.*:.*' /etc/passwd $arg && [ -d /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
-testing "adduser user_name with -H" "useradd -H toyTestUser $arg ||
- grep '^toyTestUser:.*:.*:.*' /etc/passwd $arg &&
- test ! -e /home/toyTestUser && userdel toyTestUser $arg && echo 'yes'" \
- "yes\n" "" "$pass"
+testing "adduser user_name with -H" "useradd -H $user $arg ||
+ grep '^$user:.*:.*:.*' /etc/passwd $arg && [ ! -e /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
-testing "adduser user_name with dir and -H" \
- "useradd -H -h $PWD/dir toyTestUser $arg ||
- grep '^toyTestUser:.*dir' /etc/passwd $arg && test ! -e $PWD/dir &&
- userdel toyTestUser $arg && echo 'yes'" "yes\n" "" "$pass"
+testing "adduser user_name with dir and -H" "useradd -H -h $PWD/dir $user $arg ||
+ grep '^$user:.*dir' /etc/passwd $arg && [ ! -e $PWD/dir ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
-testing "adduser user_name with user_id" "useradd -u 49999 toyTestUser $arg ||
- grep '^toyTestUser:x:49999:.*' /etc/passwd $arg &&
- test -d /home/toyTestUser && userdel toyTestUser $arg &&
- rm -rf /home/toyTestUser && echo 'yes'" "yes\n" "" "$pass"
+testing "adduser user_name with user_id" "useradd -u 49999 $user $arg ||
+ grep '^$user:x:49999:.*' /etc/passwd $arg && [ -d /home/$user ] &&
+ echo 'yes'" "yes\n" "" "$pass"
+userdel -r $user $arg
diff --git a/toys/lsb/mktemp.c b/toys/lsb/mktemp.c
index 498f9f1..cc42665 100644
--- a/toys/lsb/mktemp.c
+++ b/toys/lsb/mktemp.c
@@ -4,7 +4,7 @@
*
* http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/mktemp.html
-USE_MKTEMP(NEWTOY(mktemp, ">1q(directory)d(tmpdir)p:", TOYFLAG_BIN))
+USE_MKTEMP(NEWTOY(mktemp, ">1qd(directory)p(tmpdir):", TOYFLAG_BIN))
config MKTEMP
bool "mktemp"
@@ -40,11 +40,14 @@
if (!TT.tmpdir) TT.tmpdir = getenv("TMPDIR");
if (!TT.tmpdir) TT.tmpdir = "/tmp";
- snprintf(toybuf, sizeof(toybuf), "%s/%s", TT.tmpdir, template);
+ template = strchr(template, '/') ? xstrdup(template)
+ : xmprintf("%s/%s", TT.tmpdir, template);
- if (d_flag ? !mkdtemp(toybuf) : mkstemp(toybuf) == -1) {
+ if (d_flag ? !mkdtemp(template) : mkstemp(template) == -1) {
if (toys.optflags & FLAG_q) toys.exitval = 1;
else perror_exit("Failed to create %s %s/%s",
d_flag ? "directory" : "file", TT.tmpdir, template);
- } else xputs(toybuf);
+ } else xputs(template);
+
+ if (CFG_TOYBOX_FREE) free(template);
}
diff --git a/toys/other/dos2unix.c b/toys/other/dos2unix.c
index 690c5a8..021ba38 100644
--- a/toys/other/dos2unix.c
+++ b/toys/other/dos2unix.c
@@ -2,16 +2,25 @@
*
* Copyright 2012 Rob Landley <rob@landley.net>
-USE_DOS2UNIX(NEWTOY(dos2unix, NULL, TOYFLAG_BIN))
-USE_DOS2UNIX(OLDTOY(unix2dos, dos2unix, TOYFLAG_BIN))
+USE_DOS2UNIX(NEWTOY(dos2unix, 0, TOYFLAG_BIN))
+USE_UNIX2DOS(NEWTOY(unix2dos, 0, TOYFLAG_BIN))
config DOS2UNIX
bool "dos2unix/unix2dos"
default y
help
- usage: dos2unix/unix2dos [file...]
+ usage: dos2unix [FILE...]
- Convert newline format between dos (\r\n) and unix (just \n)
+ Convert newline format from dos "\r\n" to unix "\n".
+ If no files listed copy from stdin, "-" is a synonym for stdin.
+
+config UNIX2DOS
+ bool "unix2dos"
+ default y
+ help
+ usage: unix2dos [FILE...]
+
+ Convert newline format from unix "\n" to dos "\r\n".
If no files listed copy from stdin, "-" is a synonym for stdin.
*/
@@ -60,3 +69,8 @@
{
loopfiles(toys.optargs, do_dos2unix);
}
+
+void unix2dos_main(void)
+{
+ dos2unix_main();
+}
diff --git a/toys/pending/hwclock.c b/toys/pending/hwclock.c
index 003174f..d9ced6f 100644
--- a/toys/pending/hwclock.c
+++ b/toys/pending/hwclock.c
@@ -2,9 +2,9 @@
*
* Copyright 2014 Bilal Qureshi <bilal.jmi@gmail.com>
*
- * No Standard.
+ * No standard, but see Documentation/rtc.txt in the linux kernel source..
*
-USE_HWCLOCK(NEWTOY(hwclock, ">0(fast)f(rtc):u(utc)l(localtime)t(systz)w(systohc)s(hctosys)r(show)[!ul][!rsw]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_HWCLOCK(NEWTOY(hwclock, ">0(fast)f(rtc):u(utc)l(localtime)t(systz)s(hctosys)r(show)w(systohc)[-ul][!rtsw]", TOYFLAG_USR|TOYFLAG_BIN))
config HWCLOCK
bool "hwclock"
@@ -12,7 +12,7 @@
help
usage: hwclock [-rswtluf]
- -f FILE Use specified device file instead of /dev/rtc (--show)
+ -f FILE Use specified device file instead of /dev/rtc (--rtc)
-l Hardware clock uses localtime (--localtime)
-r Show hardware clock time (--show)
-s Set system time from hardware clock (--hctosys)
@@ -20,6 +20,7 @@
-u Hardware clock uses UTC (--utc)
-w Set hardware clock from system time (--systohc)
*/
+
#define FOR_hwclock
#include "toys.h"
#include <linux/rtc.h>
@@ -30,7 +31,7 @@
int utc;
)
-static int check_hctosys(struct dirtree* node)
+static int rtc_find(struct dirtree* node)
{
FILE *fp;
@@ -39,148 +40,99 @@
snprintf(toybuf, sizeof(toybuf), "/sys/class/rtc/%s/hctosys", node->name);
fp = fopen(toybuf, "r");
if (fp) {
- int hctosys = 0;
- int items = fscanf(fp, "%d", &hctosys);
+ int hctosys = 0, items = fscanf(fp, "%d", &hctosys);
+
fclose(fp);
if (items == 1 && hctosys == 1) {
snprintf(toybuf, sizeof(toybuf), "/dev/%s", node->name);
TT.fname = toybuf;
+
return DIRTREE_ABORT;
}
}
+
return 0;
}
-// Search /sys/class/rtc for the RTC that the system clock is set from.
-// See the kernel's Documentation/rtc.txt.
-static int open_wall_clock_rtc(int flag)
-{
- TT.fname = NULL;
- dirtree_read("/sys/class/rtc", check_hctosys);
- return TT.fname ? xopen(TT.fname, flag) : -1;
-}
-
-static int rtc_open(int flag)
-{
- if (!TT.fname) {
- int fd;
-
- if ((fd = open((TT.fname = "/dev/rtc"), flag)) != -1) return fd;
- else if ((fd = open_wall_clock_rtc(flag)) != -1) return fd;
- else TT.fname = "/dev/misc/rtc";
- }
- return xopen(TT.fname, flag);
-}
-
-static time_t get_rtc()
-{
- struct tm time;
- time_t tm;
- char *ptz_old = 0;
- int fd = rtc_open(O_RDONLY);
-
- xioctl(fd, RTC_RD_TIME, &time);
- close(fd);
- if (TT.utc) {
- ptz_old = getenv("TZ");
- if (putenv((char*)"TZ=UTC0")) perror_exit("putenv");
- tzset();
- }
- if ((tm = mktime(&time)) < 0) error_exit("mktime failed");
- if (TT.utc) {
- if (unsetenv("TZ") < 0) perror_exit("unsetenv");
- if (ptz_old && putenv(ptz_old - 3)) perror_exit("putenv");
- tzset();
- }
- return tm;
-}
-
-static void set_sysclock_from_hwclock()
-{
- struct timezone tmzone;
- struct timeval tmval;
-
- tmzone.tz_minuteswest = timezone / 60 - 60 * daylight;
- tmzone.tz_dsttime = 0;
- tmval.tv_sec = get_rtc();
- tmval.tv_usec = 0;
- if (settimeofday(&tmval, &tmzone) < 0) perror_exit("settimeofday");
-}
-
-static void set_hwclock_from_sysclock()
-{
- struct timeval tmval;
- struct tm time;
- int fd = rtc_open(O_WRONLY);
-
- if (gettimeofday(&tmval, NULL) < 0) perror_exit("gettimeofday");
- // converting a time value to broken-down UTC time
- if (TT.utc && !gmtime_r((time_t*)&tmval.tv_sec, &time))
- error_exit("gmtime_r failed");
- // converting a time value to a broken-down localtime
- else if (!(localtime_r((time_t*)&tmval.tv_sec, &time)))
- error_exit("localtime_r failed");
-
- /* The value of tm_isdst will positive if daylight saving time is in effect,
- * zero if it is not and negative if the information is not available.
- * */
- time.tm_isdst = 0;
- xioctl(fd, RTC_SET_TIME, &time);
- close(fd);
-}
-
-static void set_sysclock_timezone()
-{
- struct timezone tmzone;
- struct timeval tmval;
- struct tm *pb;
-
- if (gettimeofday(&tmval, NULL) < 0) perror_exit("gettimeofday");
- if (!(pb = localtime(&tmval.tv_sec))) error_exit("localtime failed");
- // extern long timezone => defined in header sys/time.h
- tmzone.tz_minuteswest = timezone / 60;
- if (pb->tm_isdst) tmzone.tz_minuteswest -= 60;
- tmzone.tz_dsttime = 0; // daylight saving time is not in effect
- if (gettimeofday(&tmval, NULL) < 0) perror_exit("gettimeofday");
- if (!TT.utc) tmval.tv_sec += tmzone.tz_minuteswest * 60;
- if (settimeofday(&tmval, &tmzone) < 0) perror_exit("settimeofday");
-}
-
void hwclock_main()
{
- // check for UTC
- if (!(toys.optflags & FLAG_u)) {
- FILE *fp = fopen("/etc/adjtime", "r");
+ struct timezone tzone;
+ struct timeval timeval;
+ struct tm tm;
+ time_t time;
+ int fd = -1;
- if (fp) {
- char *line = NULL;
- size_t st;
+ // check for Grenich Mean Time
+ if (toys.optflags & FLAG_u) TT.utc = 1;
+ else {
+ FILE *fp;
+ char *s = 0;
- while (0 < getline(&line, &st, fp)) {
- if (!strncmp(line, "UTC", 3)) {
- TT.utc = 1;
- break;
- }
- free(line);
- }
- fclose(fp);
- }
- } else TT.utc = 1;
-
- if (toys.optflags & FLAG_w) set_hwclock_from_sysclock();
- else if (toys.optflags & FLAG_s) set_sysclock_from_hwclock();
- else if (toys.optflags & FLAG_t) set_sysclock_timezone();
- else if ((toys.optflags & FLAG_r) || (toys.optflags & FLAG_l)
- || !*toys.optargs)
- {
- time_t tm = get_rtc();
- char *s, *pctm = ctime(&tm);
-
- // ctime() is defined as equivalent to asctime(localtime(t)),
- // which is defined to overflow its buffer rather than return NULL.
- // if (!pctm) error_exit("can't happen");
- if ((s = strrchr(pctm, '\n'))) *s = '\0';
- // TODO: implement this.
- xprintf("%s 0.000000 seconds\n", pctm);
+ for (fp = fopen("/etc/adjtime", "r");
+ fp && getline(&s, (void *)toybuf, fp)>0;
+ free(s), s = 0) TT.utc += !strncmp(s, "UTC", 3);
+ if (fp) fclose(fp);
}
+
+ if (!(toys.optflags&FLAG_t)) {
+ int w = toys.optflags & FLAG_w, flag = O_WRONLY*w;
+
+ // Open /dev/rtc (if your system has no /dev/rtc symlink, search for it).
+ if (!TT.fname && (fd = open("/dev/rtc", flag)) == -1) {
+ dirtree_read("/sys/class/rtc", rtc_find);
+ if (!TT.fname) TT.fname = "/dev/misc/rtc";
+ }
+ if (fd == -1) fd = xopen(TT.fname, flag);
+
+ // Get current time in seconds from rtc device. todo: get subsecond time
+ if (!w) {
+ char *s = s;
+
+ xioctl(fd, RTC_RD_TIME, &tm);
+ if (TT.utc) s = xtzset("UTC0");
+ if ((time = mktime(&tm)) < 0) goto bad;
+ if (TT.utc) {
+ free(xtzset(s));
+ free(s);
+ }
+ }
+ }
+
+ if (toys.optflags & (FLAG_w|FLAG_t))
+ if (gettimeofday(&timeval, 0)
+ || (TT.utc ? gmtime_r : localtime_r)(&timeval.tv_sec, &tm)) goto bad;
+
+ if (toys.optflags & FLAG_w) {
+ /* The value of tm_isdst will positive if daylight saving time is in effect,
+ * zero if it is not and negative if the information is not available.
+ * todo: so why isn't this negative...? */
+ tm.tm_isdst = 0;
+ xioctl(fd, RTC_SET_TIME, &time);
+ } else if (toys.optflags & FLAG_s) {
+ tzone.tz_minuteswest = timezone / 60 - 60 * daylight;
+ timeval.tv_sec = time;
+ timeval.tv_usec = 0; // todo: fixit
+ } else if (toys.optflags & FLAG_t) {
+ // Adjust seconds for timezone and daylight saving time
+ // extern long timezone is defined in header sys/time.h
+ tzone.tz_minuteswest = timezone / 60;
+ if (tm.tm_isdst) tzone.tz_minuteswest -= 60;
+ if (!TT.utc) timeval.tv_sec += tzone.tz_minuteswest * 60;
+ } else {
+ char *c = ctime(&time), *s = strrchr(c, '\n');
+
+ if (s) *s = '\0';
+ // TODO: implement this.
+ xprintf("%s 0.000000 seconds\n", c);
+ }
+ if (toys.optflags & (FLAG_t|FLAG_s)) {
+ tzone.tz_dsttime = 0;
+ if (settimeofday(&timeval, &tzone)) goto bad;
+ }
+
+ if (fd != -1) close(fd);
+
+ return;
+bad:
+ perror_exit("failed");
}
diff --git a/toys/posix/cp.c b/toys/posix/cp.c
index c1a438f..3dc6f2a 100644
--- a/toys/posix/cp.c
+++ b/toys/posix/cp.c
@@ -7,7 +7,7 @@
// This is subtle: MV options shared with CP must be in same order (right to
// left) as CP for FLAG_X macros to work out right.
-USE_CP(NEWTOY(cp, "<2RHLPp"USE_CP_MORE("rdaslvnF")"fi[-HLP"USE_CP_MORE("d")"]"USE_CP_MORE("[-ni]"), TOYFLAG_BIN))
+USE_CP(NEWTOY(cp, "<2RHLPp"USE_CP_MORE("rdaslvnF(remove-destination)")"fi[-HLP"USE_CP_MORE("d")"]"USE_CP_MORE("[-ni]"), TOYFLAG_BIN))
USE_MV(NEWTOY(mv, "<2"USE_CP_MORE("vnF")"fi"USE_CP_MORE("[-ni]"), TOYFLAG_BIN))
USE_INSTALL(NEWTOY(install, "<1cdDpsvm:o:g:", TOYFLAG_USR|TOYFLAG_BIN))
*
@@ -22,7 +22,7 @@
be a directory.
-f delete destination files we can't write to
- -F delete any existing destination file first (breaks hardlinks)
+ -F delete any existing destination file first (--remove-destination)
-i interactive, prompt before overwriting existing DEST
-p preserve timestamps, ownership, and permissions
-R recurse into subdirectories (DEST must be a directory)
diff --git a/toys/posix/grep.c b/toys/posix/grep.c
index 18a27e3..61df08e 100644
--- a/toys/posix/grep.c
+++ b/toys/posix/grep.c
@@ -5,8 +5,8 @@
* See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html
USE_GREP(NEWTOY(grep, "ZzEFHabhinorsvwclqe*f*m#x[!wx][!EFw]", TOYFLAG_BIN))
-USE_GREP(OLDTOY(egrep, grep, TOYFLAG_BIN))
-USE_GREP(OLDTOY(fgrep, grep, TOYFLAG_BIN))
+USE_EGREP(OLDTOY(egrep, grep, TOYFLAG_BIN))
+USE_FGREP(OLDTOY(fgrep, grep, TOYFLAG_BIN))
config GREP
bool "grep"
@@ -36,6 +36,16 @@
output prefix (default: filename if checking more than 1 file)
-H force filename -b byte offset of match
-h hide filename -n line number of match
+
+config EGREP
+ bool
+ default y
+ depends on GREP
+
+config FGREP
+ bool
+ default y
+ depends on GREP
*/
#define FOR_grep