Revert back to upstream 0.6.0 and remove all except for dhcp related 01/62701/1 submit/tizen/20160323.053424
authorYu Jiung <jiung.yu@samsung.com>
Thu, 17 Mar 2016 12:09:12 +0000 (21:09 +0900)
committerYu Jiung <jiung.yu@samsung.com>
Thu, 17 Mar 2016 12:09:12 +0000 (21:09 +0900)
Change-Id: Ide839cfefc7c4049715f86a2bf769c333175b2bf

63 files changed:
Config.in [changed mode: 0644->0755]
lib/lib.c [changed mode: 0644->0755]
lib/lib.h [changed mode: 0644->0755]
lib/net.c [changed mode: 0644->0755]
lib/portability.c [changed mode: 0644->0755]
lib/xwrap.c [changed mode: 0644->0755]
main.c [changed mode: 0644->0755]
packaging/bin_tv.links [deleted file]
packaging/config
packaging/klogd.manifest [deleted file]
packaging/klogd.service [deleted file]
packaging/sbin.links
packaging/sbin_tv.links [deleted file]
packaging/syslogd.manifest [deleted file]
packaging/syslogd.service [deleted file]
packaging/toybox.spec
packaging/usrbin.links
scripts/change.sh
scripts/mkflags.c [changed mode: 0644->0755]
tests/date.test [deleted file]
toys.h [changed mode: 0644->0755]
toys/other/acpi.c [changed mode: 0644->0755]
toys/other/blkid.c [changed mode: 0644->0755]
toys/other/bzcat.c [changed mode: 0644->0755]
toys/other/chcon.c [changed mode: 0644->0755]
toys/other/fsync.c [deleted file]
toys/other/hexedit.c [changed mode: 0644->0755]
toys/other/hostid.c [deleted file]
toys/other/login.c [changed mode: 0644->0755]
toys/other/lspci.c [changed mode: 0644->0755]
toys/other/nbd_client.c [changed mode: 0644->0755]
toys/other/netcat.c [changed mode: 0644->0755]
toys/other/reboot.c [changed mode: 0644->0755]
toys/other/rev.c [changed mode: 0644->0755]
toys/other/stat.c
toys/other/switch_root.c [changed mode: 0644->0755]
toys/other/tac.c [changed mode: 0644->0755]
toys/other/taskset.c [changed mode: 0644->0755]
toys/other/vmstat.c [changed mode: 0644->0755]
toys/pending/dd.c [changed mode: 0644->0755]
toys/pending/init.c [changed mode: 0644->0755]
toys/pending/mdev.c [changed mode: 0644->0755]
toys/pending/modprobe.c [changed mode: 0644->0755]
toys/pending/syslogd.c
toys/pending/telnet.c [changed mode: 0644->0755]
toys/pending/telnetd.c [changed mode: 0644->0755]
toys/pending/tftp.c [deleted file]
toys/posix/cal.c [changed mode: 0644->0755]
toys/posix/chmod.c [changed mode: 0644->0755]
toys/posix/cmp.c [changed mode: 0644->0755]
toys/posix/cp.c
toys/posix/date.c [changed mode: 0644->0755]
toys/posix/du.c [changed mode: 0644->0755]
toys/posix/find.c [changed mode: 0644->0755]
toys/posix/id.c [changed mode: 0644->0755]
toys/posix/ls.c [changed mode: 0644->0755]
toys/posix/nl.c [changed mode: 0644->0755]
toys/posix/split.c [changed mode: 0644->0755]
toys/posix/strings.c [changed mode: 0644->0755]
toys/samsung/README [deleted file]
toys/samsung/nslookup.c [deleted file]
www/news.html
www/roadmap.html

old mode 100644 (file)
new mode 100755 (executable)
index a2443e2..9d3a73b
--- a/Config.in
+++ b/Config.in
@@ -117,7 +117,7 @@ config TOYBOX_DEBUG
        default n
        help
          Enable extra checks for debugging purposes. All of them catch
-         things that can only go wrong at development time, not runtime.
+          things that can only go wrong at development time, not runtime.
 
 config TOYBOX_UID_SYS
        int "First system UID"
old mode 100644 (file)
new mode 100755 (executable)
index c16cffe..05e377f
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -291,41 +291,6 @@ int stridx(char *haystack, char needle)
   return off-haystack;
 }
 
-char *strlower(char *s)
-{
-  char *try, *new;
-
-  if (!CFG_TOYBOX_I18N) {
-    try = new = xstrdup(s);
-    for (; *s; s++) *(new++) = tolower(*s);
-  } else {
-    // I can't guarantee the string _won't_ expand during reencoding, so...?
-    try = new = xmalloc(strlen(s)*2+1);
-
-    while (*s) {
-      wchar_t c;
-      int len = mbrtowc(&c, s, MB_CUR_MAX, 0);
-
-      if (len < 1) *(new++) = *(s++);
-      else {
-        s += len;
-        // squash title case too
-        c = towlower(c);
-
-        // if we had a valid utf8 sequence, convert it to lower case, and can't
-        // encode back to utf8, something is wrong with your libc. But just
-        // in case somebody finds an exploit...
-        len = wcrtomb(new, c, 0);
-        if (len < 1) error_exit("bad utf8 %x", (int)c);
-        new += len;
-      }
-    }
-    *new = 0;
-  }
-
-  return try;
-}
-
 int unescape(char c)
 {
   char *from = "\\abefnrtv", *to = "\\\a\b\033\f\n\r\t\v";
@@ -575,7 +540,7 @@ void delete_tempfile(int fdin, int fdout, char **tempname)
 {
   close(fdin);
   close(fdout);
-  if (*tempname) unlink(*tempname);
+  unlink(*tempname);
   tempfile2zap = (char *)1;
   free(*tempname);
   *tempname = NULL;
@@ -868,7 +833,7 @@ void names_to_pid(char **names, int (*callback)(pid_t pid, char *name))
 
 // display first few digits of number with power of two units, except we're
 // actually just counting decimal digits and showing mil/bil/trillions.
-int human_readable(char *buf, unsigned long long num, int style)
+int human_readable(char *buf, unsigned long long num)
 {
   int end, len;
 
@@ -881,9 +846,9 @@ int human_readable(char *buf, unsigned long long num, int style)
     buf[1] = '.';
     end = 3;
   }
-  if (style & HR_SPACE) buf[end++] = ' ';
+  buf[end++] = ' ';
   if (len) buf[end++] = " KMGTPE"[len];
-  if (style & HR_B) buf[end++] = 'B';
+  buf[end++] = 'B';
   buf[end++] = 0;
 
   return end;
old mode 100644 (file)
new mode 100755 (executable)
index 17a4a97..3183f32
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -160,7 +160,6 @@ long xstrtol(char *str, char **end, int base);
 long atolx(char *c);
 long atolx_range(char *numstr, long low, long high);
 int stridx(char *haystack, char needle);
-char *strlower(char *s);
 int unescape(char c);
 int strstart(char **a, char *b);
 off_t fdlength(int fd);
@@ -177,9 +176,7 @@ void replace_tempfile(int fdin, int fdout, char **tempname);
 void crc_init(unsigned int *crc_table, int little_endian);
 void base64_init(char *p);
 int yesno(char *prompt, int def);
-#define HR_SPACE 1
-#define HR_B 2
-int human_readable(char *buf, unsigned long long num, int style);
+int human_readable(char *buf, unsigned long long num);
 int qstrcmp(const void *a, const void *b);
 int xpoll(struct pollfd *fds, int nfds, int timeout);
 
@@ -207,8 +204,6 @@ void tty_sigreset(int i);
 // net.c
 int xsocket(int domain, int type, int protocol);
 void xsetsockopt(int fd, int level, int opt, void *val, socklen_t len);
-int xconnect(char *host, char *port, int family, int socktype, int protocol,
-  int flags);
 
 // password.c
 int get_salt(char *salt, char * algo);
old mode 100644 (file)
new mode 100755 (executable)
index 48d0a5f..5d3ea4a
--- a/lib/net.c
+++ b/lib/net.c
@@ -12,33 +12,3 @@ void xsetsockopt(int fd, int level, int opt, void *val, socklen_t len)
 {
   if (-1 == setsockopt(fd, level, opt, val, len)) perror_exit("setsockopt");
 }
-
-int xconnect(char *host, char *port, int family, int socktype, int protocol,
-             int flags)
-{
-  struct addrinfo info, *ai, *ai2;
-  int fd;
-
-  memset(&info, 0, sizeof(struct addrinfo));
-  info.ai_family = family;
-  info.ai_socktype = socktype;
-  info.ai_protocol = protocol;
-  info.ai_flags = flags;
-
-  fd = getaddrinfo(host, port, &info, &ai);
-  if (fd || !ai)
-    error_exit("Connect '%s%s%s': %s", host, port ? ":" : "", port ? port : "",
-      fd ? gai_strerror(fd) : "not found");
-
-  // Try all the returned addresses. Report errors if last entry can't connect.
-  for (ai2 = ai; ai; ai = ai->ai_next) {
-    fd = (ai->ai_next ? socket : xsocket)(ai->ai_family, ai->ai_socktype,
-      ai->ai_protocol);
-    if (!connect(fd, ai->ai_addr, ai->ai_addrlen)) break;
-    else if (!ai2->ai_next) perror_exit("connect");
-    close(fd);
-  }
-  freeaddrinfo(ai2);
-
-  return fd;
-}
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 8086282..54f2cbb
@@ -30,10 +30,10 @@ void xstrncat(char *dest, char *src, size_t size)
 
 void xexit(void)
 {
-  if (toys.rebound) longjmp(*toys.rebound, 1);
   if (fflush(NULL) || ferror(stdout))
     if (!toys.exitval) perror_msg("write");
-  exit(toys.exitval);
+  if (toys.rebound) longjmp(*toys.rebound, 1);
+  else exit(toys.exitval);
 }
 
 // Die unless we can allocate memory.
@@ -136,10 +136,7 @@ void xexec(char **argv)
   if (CFG_TOYBOX && !CFG_TOYBOX_NORECURSE) toy_exec(argv);
   execvp(argv[0], argv);
 
-  perror_msg("exec %s", argv[0]);
-  toys.exitval = 127;
-  if (!CFG_TOYBOX_FORK) _exit(toys.exitval);
-  xexit();
+  perror_exit("exec %s", argv[0]);
 }
 
 // Spawn child process, capturing stdin/stdout.
diff --git a/main.c b/main.c
old mode 100644 (file)
new mode 100755 (executable)
index 0738a17..8115559
--- a/main.c
+++ b/main.c
@@ -163,10 +163,7 @@ void toybox_main(void)
       xputs(TOYBOX_VERSION);
       xexit();
     }
-    if (toys.argv[1][0] != '-') {
-      toys.exitval = 127;
-      error_exit("Unknown command %s", toys.argv[1]);
-    }
+    if (toys.argv[1][0] != '-') error_exit("Unknown command %s", toys.argv[1]);
   }
 
   // Output list of command.
diff --git a/packaging/bin_tv.links b/packaging/bin_tv.links
deleted file mode 100644 (file)
index 5c3aa65..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-ping
-ping6
index 4004694..c368e46 100644 (file)
@@ -13,32 +13,27 @@ CONFIG_TOYBOX_SHADOW=y
 CONFIG_TOYBOX_FORK=y
 
 #
-# Samsung developed commands
-#
-# CONFIG_NSLOOKUP is not set
-
-#
 # Posix commands
 #
 # CONFIG_BASENAME is not set
 # CONFIG_CAL is not set
 # CONFIG_CAT is not set
 # CONFIG_CAT_V is not set
-CONFIG_CATV=y
+# CONFIG_CATV is not set
 # CONFIG_CHGRP is not set
 # CONFIG_CHOWN is not set
 # CONFIG_CHMOD is not set
 # CONFIG_CKSUM is not set
 # CONFIG_CMP is not set
 # CONFIG_COMM is not set
-CONFIG_CP=y
-CONFIG_CP_MORE=y
-CONFIG_CP_PRESERVE=y
-CONFIG_CP_Z=y
-CONFIG_MV=y
-CONFIG_MV_MORE=y
-CONFIG_INSTALL=y
-CONFIG_INSTALL_Z=y
+# CONFIG_CP is not set
+# CONFIG_CP_MORE is not set
+# CONFIG_CP_PRESERVE is not set
+# CONFIG_CP_Z is not set
+# CONFIG_MV is not set
+# CONFIG_MV_MORE is not set
+# CONFIG_INSTALL is not set
+# CONFIG_INSTALL_Z is not set
 # CONFIG_CPIO is not set
 # CONFIG_CUT is not set
 # CONFIG_DATE is not set
@@ -63,12 +58,12 @@ CONFIG_INSTALL_Z=y
 # CONFIG_KILLALL5 is not set
 # CONFIG_LINK is not set
 # CONFIG_LN is not set
-CONFIG_LS=y
-CONFIG_LS_COLOR=y
-CONFIG_MKDIR=y
-CONFIG_MKDIR_Z=y
-CONFIG_MKFIFO=y
-CONFIG_MKFIFO_Z=y
+# CONFIG_LS is not set
+# CONFIG_LS_COLOR is not set
+# CONFIG_MKDIR is not set
+# CONFIG_MKDIR_Z is not set
+# CONFIG_MKFIFO is not set
+# CONFIG_MKFIFO_Z is not set
 # CONFIG_NICE is not set
 # CONFIG_NL is not set
 # CONFIG_NOHUP is not set
@@ -78,7 +73,7 @@ CONFIG_MKFIFO_Z=y
 # CONFIG_PRINTF is not set
 # CONFIG_PWD is not set
 # CONFIG_RENICE is not set
-CONFIG_RM=y
+# CONFIG_RM is not set
 # CONFIG_RMDIR is not set
 # CONFIG_SED is not set
 # CONFIG_SLEEP is not set
@@ -140,10 +135,10 @@ CONFIG_DUMPLEASES=y
 # CONFIG_IP is not set
 # CONFIG_IPCRM is not set
 # CONFIG_IPCS is not set
-CONFIG_KLOGD=y
-CONFIG_KLOGD_SOURCE_RING_BUFFER=y
+# CONFIG_KLOGD is not set
+# CONFIG_KLOGD_SOURCE_RING_BUFFER is not set
 # CONFIG_LAST is not set
-CONFIG_LOGGER=y
+# CONFIG_LOGGER is not set
 # CONFIG_MDEV is not set
 # CONFIG_MDEV_CONF is not set
 # CONFIG_MKE2FS is not set
@@ -164,7 +159,7 @@ CONFIG_PING=y
 # CONFIG_EXIT is not set
 # CONFIG_CD is not set
 # CONFIG_SULOGIN is not set
-CONFIG_SYSLOGD=y
+# CONFIG_SYSLOGD is not set
 # CONFIG_TAR is not set
 # CONFIG_TCPSVD is not set
 # CONFIG_TELNET is not set
@@ -187,7 +182,7 @@ CONFIG_TRACEROUTE=y
 # CONFIG_BASE64 is not set
 # CONFIG_BLKID is not set
 # CONFIG_FSTYPE is not set
-CONFIG_BLOCKDEV=y
+# CONFIG_BLOCKDEV is not set
 # CONFIG_BUNZIP2 is not set
 # CONFIG_BZCAT is not set
 # CONFIG_CHCON is not set
@@ -204,14 +199,14 @@ CONFIG_BLOCKDEV=y
 # CONFIG_FREERAMDISK is not set
 # CONFIG_FSFREEZE is not set
 # CONFIG_FSYNC is not set
-CONFIG_HELP=y
-CONFIG_HELP_EXTRAS=y
+# CONFIG_HELP is not set
+# CONFIG_HELP_EXTRAS is not set
 # CONFIG_HEXEDIT is not set
 # CONFIG_HOSTID is not set
 # CONFIG_HWCLOCK is not set
 # CONFIG_IFCONFIG is not set
 # CONFIG_INOTIFYD is not set
-CONFIG_INSMOD=y
+# CONFIG_INSMOD is not set
 # CONFIG_IONICE is not set
 # CONFIG_IORENICE is not set
 # CONFIG_LOGIN is not set
@@ -249,8 +244,8 @@ CONFIG_INSMOD=y
 # CONFIG_RMMOD is not set
 # CONFIG_SETSID is not set
 # CONFIG_SHRED is not set
-CONFIG_STAT=y
-CONFIG_STAT_C=y
+# CONFIG_STAT is not set
+# CONFIG_STAT_C is not set
 # CONFIG_SWAPOFF is not set
 # CONFIG_SWAPON is not set
 # CONFIG_SWITCH_ROOT is not set
@@ -277,16 +272,16 @@ CONFIG_STAT_C=y
 # CONFIG_KILLALL is not set
 # CONFIG_MD5SUM is not set
 # CONFIG_SHA1SUM is not set
-CONFIG_MKNOD=y
-CONFIG_MKNOD_Z=y
-CONFIG_MKTEMP=y
-CONFIG_MOUNT=y
+# CONFIG_MKNOD is not set
+# CONFIG_MKNOD_Z is not set
+# CONFIG_MKTEMP is not set
+# CONFIG_MOUNT is not set
 # CONFIG_PASSWD is not set
 # CONFIG_PIDOF is not set
 # CONFIG_SEQ is not set
 # CONFIG_SU is not set
 # CONFIG_SYNC is not set
-CONFIG_UMOUNT=y
+# CONFIG_UMOUNT is not set
 
 #
 # Example commands
diff --git a/packaging/klogd.manifest b/packaging/klogd.manifest
deleted file mode 100644 (file)
index 97e8c31..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<manifest>
-       <request>
-               <domain name="_"/>
-       </request>
-</manifest>
diff --git a/packaging/klogd.service b/packaging/klogd.service
deleted file mode 100644 (file)
index 03df845..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-[Unit]
-Description=Run syslog
-DefaultDependencies=no
-After=syslogd.service
-ConditionKernelCommandLine=|!sec_debug.enable=0
-ConditionKernelCommandLine=|!sec_debug.enable_user=0
-
-[Service]
-Type=forking
-ExecStart=/sbin/klogd
-OOMScoreAdjust=-1000
-Restart=always
-RestartSec=0
-
-[Install]
-WantedBy=basic.target
index ff4418a..e69de29 100644 (file)
@@ -1,2 +0,0 @@
-klogd
-syslogd
diff --git a/packaging/sbin_tv.links b/packaging/sbin_tv.links
deleted file mode 100644 (file)
index 02d4a98..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-klogd
-syslogd
-ping
-ping6
diff --git a/packaging/syslogd.manifest b/packaging/syslogd.manifest
deleted file mode 100644 (file)
index 97e8c31..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<manifest>
-       <request>
-               <domain name="_"/>
-       </request>
-</manifest>
diff --git a/packaging/syslogd.service b/packaging/syslogd.service
deleted file mode 100644 (file)
index 7b10609..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-[Unit]
-Description=Run syslog
-DefaultDependencies=no
-After=local-fs.target
-ConditionKernelCommandLine=|!sec_debug.enable=0
-ConditionKernelCommandLine=|!sec_debug.enable_user=0
-
-[Service]
-Type=forking
-ExecStart=/sbin/syslogd -b 5 -B 99
-OOMScoreAdjust=-1000
-Restart=always
-RestartSec=0
-
-[Install]
-WantedBy=basic.target
index dd6d12f..0f46c58 100644 (file)
@@ -7,20 +7,11 @@ License: BSD-2-Clause-FreeBSD
 URL: http://www.landley.net/toybox/
 Source: %{name}-%{version}.tar.bz2
 Source1: config
-%if "%{?profile}"=="tv"
-Source2: bin_tv.links
-Source3: sbin_tv.links
-%else
 Source2: bin.links
 Source3: sbin.links
-%endif
 Source4: usrbin.links
 Source5: usrsbin.links
-Source101: klogd.service
-Source102: syslogd.service
 Source1001: toybox.manifest
-Source1002: syslogd.manifest
-Source1003: klogd.manifest
 
 BuildRequires : smack-devel
 BuildRequires : libattr-devel
@@ -31,22 +22,6 @@ of system commands, including a shell.  This package can be very
 useful for recovering from certain types of system failures,
 particularly those involving broken shared libraries.
 
-%package symlinks-klogd
-Group: tools
-Summary: ToyBox symlinks to provide 'klogd'
-Requires: %{name} = %{version}-%{release}
-
-%description symlinks-klogd
-ToyBox symlinks for utilities corresponding to 'klogd' package.
-
-%package symlinks-sysklogd
-Group: tools
-Summary: ToyBox symlinks to provide 'sysklogd'
-Requires: %{name} = %{version}-%{release}
-
-%description symlinks-sysklogd
-ToyBox symlinks for utilities corresponding to 'sysklogd' package.
-
 %package symlinks-dhcp
 Group: tools
 Summary: ToyBox symlinks to provide 'dhcp'
@@ -68,8 +43,6 @@ ToyBox symlinks for utilities corresponding to 'dhcpd' package.
 
 %build
 cp %{SOURCE1001} .
-cp %{SOURCE1002} .
-cp %{SOURCE1003} .
 # create dynamic toybox - the executable is toybox
 cp %{SOURCE1} .config
 make -j 4 CC="gcc $RPM_OPT_FLAGS" CFLAGS="$CFLAGS -fPIE" LDOPTIMIZE="-Wl,--gc-sections -pie"
@@ -94,63 +67,21 @@ cd ../../usr/sbin
 for f in `cat %SOURCE5` ; do ln -s ../../bin/toybox $f ; done
 popd
 
-# install systemd service files for syslogd and klogd
-#mkdir -p  %{buildroot}%{_unitdir}/basic.target.wants
-#install -m 644 %SOURCE101  %{buildroot}%{_unitdir}/klogd.service
-#ln -s ../klogd.service  %{buildroot}%{_unitdir}/basic.target.wants/klogd.service
-#install -m 644 %SOURCE102  %{buildroot}%{_unitdir}/syslogd.service
-#ln -s ../syslogd.service  %{buildroot}%{_unitdir}/basic.target.wants/syslogd.service
-#rm -rf $RPM_BUILD_ROOT/sbin/syslogd
-#cp -f $RPM_BUILD_ROOT/bin/toybox $RPM_BUILD_ROOT/sbin/syslogd
-#rm -rf $RPM_BUILD_ROOT/sbin/klogd
-#cp -f $RPM_BUILD_ROOT/bin/toybox $RPM_BUILD_ROOT/sbin/klogd
-
-mkdir -p $RPM_BUILD_ROOT%{_datadir}/license
-cat LICENSE > $RPM_BUILD_ROOT%{_datadir}/license/toybox
-cat LICENSE > $RPM_BUILD_ROOT%{_datadir}/license/toybox-symlinks-klogd
-cat LICENSE > $RPM_BUILD_ROOT%{_datadir}/license/toybox-symlinks-sysklogd
-cat LICENSE > $RPM_BUILD_ROOT%{_datadir}/license/toybox-symlinks-dhcp
-cat LICENSE > $RPM_BUILD_ROOT%{_datadir}/license/toybox-symlinks-dhcpd
-
 %files
-%defattr(-,root,root,-)
-%doc LICENSE
-%{_datadir}/license/toybox
-/bin/toybox
-/usr/bin/nslookup
-%if "%{?profile}"=="tv"
-/sbin/ping
-/bin/ping
-/sbin/ping6
-/bin/ping6
-%endif
 %manifest toybox.manifest
-
-%files symlinks-klogd
-%defattr(-,root,root,-)
-%{_datadir}/license/toybox-symlinks-klogd
-/sbin/klogd
-#%{_unitdir}/klogd.service
-#%{_unitdir}/basic.target.wants/klogd.service
-%manifest klogd.manifest
-
-%files symlinks-sysklogd
+%license LICENSE
 %defattr(-,root,root,-)
-%{_datadir}/license/toybox-symlinks-sysklogd
-/sbin/syslogd
-#%{_unitdir}/syslogd.service
-#%{_unitdir}/basic.target.wants/syslogd.service
-%manifest syslogd.manifest
+/bin/toybox
 
 %files symlinks-dhcp
+%manifest toybox.manifest
+%license LICENSE
 %defattr(-,root,root,-)
-%{_datadir}/license/toybox-symlinks-dhcp
 %{_bindir}/dhcp
-%manifest toybox.manifest
 
 %files symlinks-dhcpd
+%manifest toybox.manifest
+%license LICENSE
 %defattr(-,root,root,-)
-%{_datadir}/license/toybox-symlinks-dhcpd
 %{_bindir}/dumpleases
 %{_sbindir}/dhcpd
-%manifest toybox.manifest
index 2ed0e8d..424150e 100644 (file)
@@ -1,3 +1,2 @@
 dumpleases
 dhcp
-nslookup
index 99dcfde..dcd581e 100755 (executable)
@@ -18,4 +18,3 @@ do
   scripts/single.sh $i > /dev/null 2>$PREFIX/${i}.bad &&
     rm $PREFIX/${i}.bad || echo -n '*'
 done
-echo
old mode 100644 (file)
new mode 100755 (executable)
index 7e57f84..d87087b
@@ -6,12 +6,10 @@
 // This is intentionally crappy code because we control the inputs. It leaks
 // memory like a sieve and segfaults if malloc returns null, but does the job.
 
-#include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <ctype.h>
 
 struct flag {
   struct flag *next;
diff --git a/tests/date.test b/tests/date.test
deleted file mode 100644 (file)
index 94a4157..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-
-[ -f testing.sh ] && . testing.sh
-
-#testing "name" "command" "result" "infile" "stdin"
-
-# Test Unix date parsing.
-testing "date -d @0" "TZ=UTC date -d @0 2>&1" "Thu Jan  1 00:00:00 GMT 1970\n" "" ""
-testing "date -d @0x123" "TZ=UTC date -d @0x123 2>&1" "date: bad date '@0x123'\n" "" ""
-
-# Test basic date parsing.
-# Note that toybox's -d format is not the same as coreutils'.
-testing "date -d 06021234" "TZ=UTC date -d 06021234 2>&1" "Sun Jun  2 12:34:00 UTC 1900\n" "" ""
-testing "date -d 060212341982" "TZ=UTC date -d 060212341982 2>&1" "Sun Jun  2 12:34:00 UTC 1982\n" "" ""
-testing "date -d 123" "TZ=UTC date -d 123 2>&1" "date: bad date '123'\n" "" ""
-
-# Accidentally given a Unix time, we should trivially reject that.
-testing "date Unix time missing @" "TZ=UTC date 1438053157 2>&1" \
-  "date: bad date '1438053157'; Tue February 38 05:31:00 UTC 2057 != Sun Mar 10 05:31:00 UTC 2058\n" "" ""
-# But some invalid dates are more subtle, like Febuary 29th in a non-leap year.
-testing "date Feb 29th" "TZ=UTC date 022900001975 2>&1" \
-  "date: bad date '022900001975'; Tue Feb 29 00:00:00 UTC 2075 != Fri Mar  1 00:00:00 UTC 2075\n" "" ""
diff --git a/toys.h b/toys.h
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 363cfb9..44fd03b
@@ -25,7 +25,10 @@ config ACPI
 #include "toys.h"
 
 GLOBALS(
-  int ac, bat, therm, cool;
+  int ac;
+  int bat;
+  int therm;
+  int cool;
   char *cpath;
 )
 
@@ -41,7 +44,7 @@ int read_int_at(int dirfd, char *name)
   return ret;
 }
 
-static int acpi_callback(struct dirtree *tree)
+int acpi_callback(struct dirtree *tree)
 {
   int dfd, fd, len, on;
 
@@ -82,11 +85,11 @@ done:
   return 0;
 }
 
-static int temp_callback(struct dirtree *tree)
+int temp_callback(struct dirtree *tree)
 {
   int dfd, temp;
 
-  if (*tree->name=='.') return 0;
+  if (tree->name[0]=='.') return 0;
   if (!tree->parent || !tree->parent->parent)
     return DIRTREE_RECURSE|DIRTREE_SYMFOLLOW;
   errno = 0;
@@ -95,17 +98,17 @@ static int temp_callback(struct dirtree *tree)
     if ((0 < (temp = read_int_at(dfd, "temp"))) || !errno) {
       //some tempertures are in milli-C, some in deci-C
       //reputedly some are in deci-K, but I have not seen them
-      if (((temp >= 1000) || (temp <= -1000)) && (temp%100 == 0)) temp /= 100;
+      if (((temp >= 1000) || (temp <= -1000)) && (temp%100 == 0))
+        temp /= 100;
       printf("Thermal %d: %d.%d degrees C\n", TT.therm++, temp/10, temp%10);
     }
     close(dfd);
   }
   free(TT.cpath);
-
   return 0;
 }
 
-static int cool_callback(struct dirtree *tree)
+int cool_callback(struct dirtree *tree)
 {
   int dfd=5, cur, max;
 
old mode 100644 (file)
new mode 100755 (executable)
index fad1159..725f163
@@ -4,7 +4,7 @@
  *
  * See ftp://ftp.kernel.org/pub/linux/utils/util-linux/v2.24/libblkid-docs/api-index-full.html
 
-USE_BLKID(NEWTOY(blkid, 0, TOYFLAG_BIN))
+USE_BLKID(NEWTOY(blkid, "<1", TOYFLAG_BIN))
 USE_FSTYPE(NEWTOY(fstype, "<1", TOYFLAG_BIN))
 
 config BLKID
@@ -34,7 +34,6 @@ struct fstype {
 };
 
 static const struct fstype fstypes[] = {
-  {"swap", 0x4341505350415753, 8, 4086, 1036, 15, 1052},
   {"ext2", 0xEF53, 2, 1080, 1128, 16, 1144}, // keep this first for ext3/4 check
   // NTFS label actually 8/16 0x4d80 but horrible: 16 bit wide characters via
   // codepage, something called a uuid that's only 8 bytes long...
@@ -57,7 +56,8 @@ static const struct fstype fstypes[] = {
   {"vfat", 0x31544146, 4, 54, 39+(4<<24), 11, 43}     // fat1
 };
 
-static void do_blkid(int fd, char *name)
+/* TODO if no args use proc/partitions */
+void do_blkid(int fd, char *name)
 {
   int off, i, j;
   char *type;
@@ -89,7 +89,7 @@ static void do_blkid(int fd, char *name)
       if (test == fstypes[i].magic) break;
     }
 
-    if (i == ARRAY_LEN(fstypes)) {
+    if (i == sizeof(fstypes)/sizeof(struct fstype)) {
       off += len;
       if (pass) continue;
       return;
@@ -136,30 +136,10 @@ static void do_blkid(int fd, char *name)
 
 void blkid_main(void)
 {
-  if (*toys.optargs) loopfiles(toys.optargs, do_blkid);
-  else {
-    unsigned int ma, mi, sz, fd;
-    char *name = toybuf, *buffer = toybuf+1024, device[32];
-    FILE *fp = xfopen("/proc/partitions", "r");
-
-    while (fgets(buffer, 1024, fp)) {
-      *name = 0;
-      if (sscanf(buffer, " %u %u %u %[^\n ]", &ma, &mi, &sz, name) != 4)
-        continue;
-
-      sprintf(device, "/dev/%.20s", name);
-      if (-1 == (fd = open(device, O_RDONLY))) {
-        if (errno != ENOMEDIUM) perror_msg("%s", device);
-      } else {
-        do_blkid(fd, device);
-        close(fd);
-      }
-    }
-    if (CFG_TOYBOX_FREE) fclose(fp);
-  }
+  loopfiles(toys.optargs, do_blkid);
 }
 
 void fstype_main(void)
 {
-  loopfiles(toys.optargs, do_blkid);
+  blkid_main();
 }
old mode 100644 (file)
new mode 100755 (executable)
index 850c51c..642590d
@@ -1,4 +1,4 @@
-/* bzcat.c - bzip2 decompression
+/* bzcat.c - decompress stdin to stdout using bunzip2.
  *
  * Copyright 2003, 2007 Rob Landley <rob@landley.net>
  *
 
 
 USE_BZCAT(NEWTOY(bzcat, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_BUNZIP2(NEWTOY(bunzip2, "cftkv", TOYFLAG_USR|TOYFLAG_BIN))
-
-config BUNZIP2
-  bool "bunzip2"
-  default y
-  help
-    usage: bunzip2 [-cftkv] [FILE...]
-
-    Decompress listed files (file.bz becomes file) deleting archive file(s).
-    Read from stdin if no files listed.
-
-    -c force output to stdout
-    -f force decompression. (If FILE doesn't end in .bz, replace original.)
-    -k keep input files (-c and -t imply this)
-    -t  test integrity
-    -v verbose
 
 config BZCAT
   bool "bzcat"
   default y
   help
-    usage: bzcat [FILE...]
+    usage: bzcat [filename...]
 
     Decompress listed files to stdout. Use stdin if no files listed.
 */
 
-#define FOR_bunzip2
 #include "toys.h"
 
 #define THREADS 1
@@ -438,7 +421,7 @@ static int read_huffman_data(struct bunzip_data *bd, struct bwdata *bw)
 }
 
 // Flush output buffer to disk
-static void flush_bunzip_outbuf(struct bunzip_data *bd, int out_fd)
+void flush_bunzip_outbuf(struct bunzip_data *bd, int out_fd)
 {
   if (bd->outbufPos) {
     if (write(out_fd, bd->outbuf, bd->outbufPos) != bd->outbufPos)
@@ -447,7 +430,7 @@ static void flush_bunzip_outbuf(struct bunzip_data *bd, int out_fd)
   }
 }
 
-static void burrows_wheeler_prep(struct bunzip_data *bd, struct bwdata *bw)
+void burrows_wheeler_prep(struct bunzip_data *bd, struct bwdata *bw)
 {
   int ii, jj;
   unsigned int *dbuf = bw->dbuf;
@@ -491,7 +474,7 @@ static void burrows_wheeler_prep(struct bunzip_data *bd, struct bwdata *bw)
 }
 
 // Decompress a block of text to intermediate buffer
-static int read_bunzip_data(struct bunzip_data *bd)
+int read_bunzip_data(struct bunzip_data *bd)
 {
   int rc = read_block_header(bd, bd->bwdata);
   if (!rc) rc=read_huffman_data(bd, bd->bwdata);
@@ -510,8 +493,7 @@ static int read_bunzip_data(struct bunzip_data *bd)
 // http://dogma.net/markn/articles/bwt/bwt.htm
 // http://marknelson.us/1996/09/01/bwt/
 
-static int write_bunzip_data(struct bunzip_data *bd, struct bwdata *bw,
-  int out_fd, char *outbuf, int len)
+int write_bunzip_data(struct bunzip_data *bd, struct bwdata *bw, int out_fd, char *outbuf, int len)
 {
   unsigned int *dbuf = bw->dbuf;
   int count, pos, current, run, copies, outbyte, previous, gotcount = 0;
@@ -602,8 +584,7 @@ dataus_interruptus:
 
 // Allocate the structure, read file header. If !len, src_fd contains
 // filehandle to read from. Else inbuf contains data.
-static int start_bunzip(struct bunzip_data **bdp, int src_fd, char *inbuf,
-  int len)
+int start_bunzip(struct bunzip_data **bdp, int src_fd, char *inbuf, int len)
 {
   struct bunzip_data *bd;
   unsigned int i;
@@ -641,10 +622,10 @@ static int start_bunzip(struct bunzip_data **bdp, int src_fd, char *inbuf,
 
 // Example usage: decompress src_fd to dst_fd. (Stops at end of bzip data,
 // not end of file.)
-static char *bunzipStream(int src_fd, int dst_fd)
+void bunzipStream(int src_fd, int dst_fd)
 {
   struct bunzip_data *bd;
-  char *bunzip_errors[] = {0, "not bzip", "bad data", "old format"};
+  char *bunzip_errors[]={NULL, "not bzip", "bad data", "old format"};
   int i, j;
 
   if (!(i = start_bunzip(&bd,src_fd, 0, 0))) {
@@ -655,67 +636,15 @@ static char *bunzipStream(int src_fd, int dst_fd)
 
   for (j=0; j<THREADS; j++) free(bd->bwdata[j].dbuf);
   free(bd);
-
-  return bunzip_errors[-i];
+  if (i) error_exit(bunzip_errors[-i]);
 }
 
 static void do_bzcat(int fd, char *name)
 {
-  char *err = bunzipStream(fd, 1);
-
-  if (err) error_exit(err);
+  bunzipStream(fd, 1);
 }
 
 void bzcat_main(void)
 {
   loopfiles(toys.optargs, do_bzcat);
 }
-
-static void do_bunzip2(int fd, char *name)
-{
-  int outfd = 1, rename = 0, len = strlen(name);
-  char *tmp, *err, *dotbz = 0;
-
-  // Trim off .bz or .bz2 extension
-  dotbz = name+len-3;
-  if ((len>3 && !strcmp(dotbz, ".bz")) || (len>4 && !strcmp(--dotbz, ".bz2")))
-    dotbz = 0;
-
-  // For - no replace
-  if (toys.optflags&FLAG_t) outfd = xopen("/dev/null", O_WRONLY);
-  else if ((fd || strcmp(name, "-")) && !(toys.optflags&FLAG_c)) {
-    if (toys.optflags&FLAG_k) {
-      if (!dotbz || !access(name, X_OK)) {
-        error_msg("%s exists", name);
-
-        return;
-      }
-    }
-    outfd = copy_tempfile(fd, name, &tmp);
-    rename++;
-  }
-
-  if (toys.optflags&FLAG_v) printf("%s:", name);
-  err = bunzipStream(fd, outfd);
-  if (toys.optflags&FLAG_v) {
-    printf("%s\n", err ? err : "ok");
-    toys.exitval |= !!err;
-  } else if (err) error_msg(err);
-
-  // can't test outfd==1 because may have been called with stdin+stdout closed
-  if (rename) {
-    if (toys.optflags&FLAG_k) {
-      free(tmp);
-      tmp = 0;
-    } else {
-      if (dotbz) *dotbz = '.';
-      if (!unlink(name)) perror_msg("%s", name);
-    }
-    (err ? delete_tempfile : replace_tempfile)(-1, outfd, &tmp);
-  }
-}
-
-void bunzip2_main(void)
-{
-  loopfiles(toys.optargs, do_bunzip2);
-}
old mode 100644 (file)
new mode 100755 (executable)
index 6dbdd13..a2bbb66
@@ -21,7 +21,7 @@ config CHCON
 #define FOR_chcon
 #include "toys.h"
 
-static int do_chcon(struct dirtree *try)
+int do_chcon(struct dirtree *try)
 {
   char *path, *con = *toys.optargs;
 
diff --git a/toys/other/fsync.c b/toys/other/fsync.c
deleted file mode 100644 (file)
index e6f6c8d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* fsync.c - Synchronize a file's in-core state with storage device.
- *
- * Copyright 2015 Ranjan Kumar <ranjankumar.bth@gmail.comi>
- *
- * No Standard.
-
-USE_FSYNC(NEWTOY(fsync, "<1d", TOYFLAG_BIN))
-
-config FSYNC
-  bool "fsync"
-  default y
-  help
-    usage: fsync [-d] [FILE...]
-
-    Synchronize a file's in-core state with storage device.
-
-    -d Avoid syncing metadata.
-*/
-
-#define FOR_fsync
-#include "toys.h"
-
-static void do_fsync(int fd, char *name)
-{
-  if (((toys.optflags & FLAG_d) ? fdatasync(fd) : fsync(fd)))
-    perror_msg("can't sync '%s'", name);
-}
-
-void fsync_main(void)
-{
-  loopfiles_rw(toys.optargs, O_RDONLY|O_NOATIME|O_NOCTTY|O_CLOEXEC,
-      0, 0, do_fsync);
-}
old mode 100644 (file)
new mode 100755 (executable)
index a52d66d..1f6b42e
@@ -137,8 +137,6 @@ void hexedit_main(void)
       fd = xopen(*toys.optargs, ro ? O_RDONLY : O_RDWR);
   char keybuf[16];
 
-  *keybuf = 0;
-
   // Terminal setup
   TT.height = 25;
   terminal_size(0, &TT.height);
diff --git a/toys/other/hostid.c b/toys/other/hostid.c
deleted file mode 100644 (file)
index 883ac3c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* hostid.c - Print the numeric identifier for the current host.
- *
- * Copyright 2015 Ranjan Kumar <ranjankumar.bth@gmail.com>
- *
- * No Standard.
-
-USE_HOSTID(NEWTOY(hostid, ">0", TOYFLAG_USR|TOYFLAG_BIN))
-
-config HOSTID
-  bool "hostid"
-  default y
-  help
-    usage: hostid
-
-    Print the numeric identifier for the current host.
-*/
-#define FOR_hostid
-#include "toys.h"
-
-void hostid_main(void)
-{
-  xprintf("%08lx\n", gethostid());
-}
old mode 100644 (file)
new mode 100755 (executable)
index c727bf9..b728286
@@ -8,28 +8,30 @@
  * TODO: this command predates "pending" but needs cleanup. It #defines
  * random stuff, calls exit() form a signal handler... yeah.
 
-USE_LOGIN(NEWTOY(login, ">1f:ph:", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
+USE_LOGIN(NEWTOY(login, ">1fph:", TOYFLAG_BIN))
 
 config LOGIN
   bool "login"
   default y
   depends on TOYBOX_SHADOW
   help
-    usage: login [-p] [-h host] [-f USERNAME] [USERNAME]
+    usage: login [-p] [-h host] [[-f] username]
 
-    Log in as a user, prompting for username and password if necessary.
+    Establish a new session with the system.
 
     -p Preserve environment
     -h The name of the remote host for this login
-    -f login as USERNAME without authentication
+    -f Do not perform authentication
 */
 
 #define FOR_login
 #include "toys.h"
 
+#define USER_NAME_MAX_SIZE 32
+#define HOSTNAME_SIZE 32
+
 GLOBALS(
   char *hostname;
-  char *username;
 
   int login_timeout, login_fail_timeout;
 )
@@ -40,128 +42,184 @@ static void login_timeout_handler(int sig __attribute__((unused)))
   exit(0);
 }
 
+static char *forbid[] = {
+  "BASH_ENV", "ENV", "HOME", "IFS", "LD_LIBRARY_PATH", "LD_PRELOAD",
+  "LD_TRACE_LOADED_OBJECTS", "LD_BIND_NOW", "LD_AOUT_LIBRARY_PATH",
+  "LD_AOUT_PRELOAD", "LD_NOWARN", "LD_KEEPDIR", "SHELL", NULL
+};
+
+int verify_password(char * pwd)
+{
+  char *pass;
+
+  if (read_password(toybuf, sizeof(toybuf), "Password: ")) return 1;
+  if (!pwd) return 1;
+  if (pwd[0] == '!' || pwd[0] == '*') return 1;
+
+  pass = crypt(toybuf, pwd);
+  if (pass && !strcmp(pass, pwd)) return 0;
+
+  return 1;
+}
+
+void read_user(char * buff, int size)
+{
+  char hostname[HOSTNAME_SIZE+1];
+  int i = 0;
+
+  hostname[HOSTNAME_SIZE] = 0;
+  if (!gethostname(hostname, HOSTNAME_SIZE)) fputs(hostname, stdout);
+
+  fputs(" login: ", stdout);
+  fflush(stdout);
+
+  do {
+    int c = getchar();
+    if (c == EOF) exit(EXIT_FAILURE);
+    *buff = c;
+  } while (isblank(*buff));
+
+  if (*buff != '\n') if(!fgets(&buff[1], HOSTNAME_SIZE-1, stdin)) _exit(1);
+
+  while(i<HOSTNAME_SIZE-1 && isgraph(buff[i])) i++;
+  buff[i] = 0;
+}
+
+void handle_nologin(void)
+{
+  int fd = open("/etc/nologin", O_RDONLY);
+  int size;
+
+  if (fd == -1) return;
+
+  size = readall(fd, toybuf,sizeof(toybuf)-1);
+  toybuf[size] = 0;
+  if (!size) puts("System closed for routine maintenance\n");
+  else puts(toybuf);
+
+  close(fd);
+  fflush(stdout);
+  exit(1);
+}
+
+void handle_motd(void)
+{
+  int fd = open("/etc/motd", O_RDONLY);
+  int size;
+  if (fd == -1) return;
+
+  size = readall(fd, toybuf,sizeof(toybuf)-1);
+  toybuf[size] = 0;
+  puts(toybuf);
+
+  close(fd);
+  fflush(stdout);
+}
+
+void spawn_shell(const char *shell)
+{
+  const char * exec_name = strrchr(shell,'/');
+  if (exec_name) exec_name++;
+  else exec_name = shell;
+
+  snprintf(toybuf,sizeof(toybuf)-1, "-%s", shell);
+  execl(shell, toybuf, NULL);
+  error_exit("Failed to spawn shell");
+}
+
+void setup_environment(const struct passwd *pwd, int clear_env)
+{
+  if (chdir(pwd->pw_dir)) printf("bad home dir: %s\n", pwd->pw_dir);
+
+  if (clear_env) {
+    const char *term = getenv("TERM");
+    clearenv();
+    if (term) setenv("TERM", term, 1);
+  }
+
+  setenv("USER", pwd->pw_name, 1);
+  setenv("LOGNAME", pwd->pw_name, 1);
+  setenv("HOME", pwd->pw_dir, 1);
+  setenv("SHELL", pwd->pw_shell, 1);
+}
+
 void login_main(void)
 {
-  char *forbid[] = {
-    "BASH_ENV", "ENV", "HOME", "IFS", "LD_LIBRARY_PATH", "LD_PRELOAD",
-    "LD_TRACE_LOADED_OBJECTS", "LD_BIND_NOW", "LD_AOUT_LIBRARY_PATH",
-    "LD_AOUT_PRELOAD", "LD_NOWARN", "LD_KEEPDIR", "SHELL"
-  };
-  int hh = toys.optflags&FLAG_h, count, tty;
-  char uu[33], *username, *pass = 0, *ss;
-  struct passwd *pwd = 0;
+  int f_flag = toys.optflags & FLAG_f;
+  int h_flag = toys.optflags & FLAG_h;
+  char username[33], *pass = NULL, **ss;
+  struct passwd * pwd = NULL;
+  struct spwd * spwd = NULL;
+  int auth_fail_cnt = 0;
+
+  if (f_flag && toys.optc != 1) error_exit("-f requires username");
 
-  for (tty=0; tty<3; tty++) if (isatty(tty)) break;
-  if (tty == 3) error_exit("no tty");
+  if (geteuid()) error_exit("not root");
 
-  for (count = 0; count < ARRAY_LEN(forbid); count++) unsetenv(forbid[count]);
+  if (!isatty(0) || !isatty(1) || !isatty(2)) error_exit("no tty");
 
   openlog("login", LOG_PID | LOG_CONS, LOG_AUTH);
   xsignal(SIGALRM, login_timeout_handler);
+  alarm(TT.login_timeout = 60);
 
-  if (TT.username) username = TT.username;
-  else username = *toys.optargs;
-  for (count = 0; count < 3; count++) {
-    alarm(TT.login_timeout = 60);
-    tcflush(0, TCIFLUSH);
-
-    if (!username) {
-      int i;
+  for (ss = forbid; *ss; ss++) unsetenv(*ss);
 
-      memset(username = uu, 0, sizeof(uu));
-      gethostname(uu, sizeof(uu)-1);
-      printf("%s%slogin: ", *uu ? uu : "", *uu ? " " : "");
-      fflush(stdout);
-
-      if(!fgets(uu, sizeof(uu)-1, stdin)) _exit(1);
+  while (1) {
+    tcflush(0, TCIFLUSH);
 
-      // Remove trailing \n and so on
-      for (i = 0; i<sizeof(uu); i++) if (uu[i]<=' ' || uu[i]==':') uu[i]=0;
-      if (!*uu) {
-        username = 0;
-        continue;
-      }
+    username[sizeof(username)-1] = 0;
+    if (*toys.optargs) xstrncpy(username, *toys.optargs, sizeof(username));
+    else {
+      read_user(username, sizeof(username));
+      if (!*username) continue;
     }
 
-    // If user exists and isn't locked
     pwd = getpwnam(username);
-    if (pwd && *pwd->pw_passwd != '!' && *pwd->pw_passwd != '*') {
+    if (!pwd) goto query_pass; // Non-existing user
 
-      // Pre-authenticated or passwordless
-      if (TT.username || !*pwd->pw_passwd) break;
+    if (pwd->pw_passwd[0] == '!' || pwd->pw_passwd[0] == '*')
+      goto query_pass;  // Locked account
 
-      // fetch shadow password if necessary
-      if (*(pass = pwd->pw_passwd) == 'x') {
-        struct spwd *spwd = getspnam (username);
+    if (f_flag) break; // Pre-authenticated
 
-        if (spwd) pass = spwd->sp_pwdp;
-      }
-    } else if (TT.username) error_exit("bad -f '%s'", TT.username);
+    if (!pwd->pw_passwd[0]) break; // Password-less account
 
-    // Verify password. (Prompt for password _before_ checking disable state.)
-    if (!read_password(toybuf, sizeof(toybuf), "Password: ")) {
-      int x = pass && (ss = crypt(toybuf, pass)) && !strcmp(pass, ss);
-
-      // password go bye-bye now.
-      memset(toybuf, 0, sizeof(toybuf));
-      if (x) break;
+    pass = pwd->pw_passwd;
+    if (pwd->pw_passwd[0] == 'x') {
+      spwd = getspnam (username);
+      if (spwd) pass = spwd->sp_pwdp;
     }
 
-    syslog(LOG_WARNING, "invalid password for '%s' on %s %s%s", pwd->pw_name,
-      ttyname(tty), hh ? "from " : "", hh ? TT.hostname : "");
+query_pass:
+    if (!verify_password(pass)) break;
+
+    f_flag = 0;
+    syslog(LOG_WARNING, "invalid password for '%s' on %s %s %s", username,
+      ttyname(0), h_flag?"from":"", h_flag?TT.hostname:"");
 
     sleep(3);
     puts("Login incorrect");
 
-    username = 0;
+    if (++auth_fail_cnt == 3)
+      error_exit("Maximum number of tries exceeded (3)\n");
+
+    *username = 0;
     pwd = 0;
+    spwd = 0;
   }
 
   alarm(0);
-  // This had password data in it, and we reuse for motd below
-  memset(toybuf, 0, sizeof(toybuf));
-
-  if (!pwd) error_exit("max retries (3)");
 
-  // Check twice because "this file exists" is a security test, and in
-  // theory filehandle exhaustion or other error could make open/read fail.
-  if (pwd->pw_uid && !access("/etc/nologin", R_OK)) {
-    ss = readfile("/etc/nologin", toybuf, sizeof(toybuf));
-    puts ((ss && *ss) ? ss : "nologin");
-    free(ss);
-    toys.exitval = 1;
-
-    return;
-  }
+  if (pwd->pw_uid) handle_nologin();
 
   xsetuser(pwd);
 
-  if (chdir(pwd->pw_dir)) printf("bad $HOME: %s\n", pwd->pw_dir);
-
-  if (!(toys.optflags&FLAG_p)) {
-    char *term = getenv("TERM");
-
-    clearenv();
-    if (term) setenv("TERM", term, 1);
-  }
-
-  setenv("USER", pwd->pw_name, 1);
-  setenv("LOGNAME", pwd->pw_name, 1);
-  setenv("HOME", pwd->pw_dir, 1);
-  setenv("SHELL", pwd->pw_shell, 1);
+  setup_environment(pwd, !(toys.optflags & FLAG_p));
 
-  // Message of the day
-  if ((ss = readfile("/etc/motd", 0, 0))) {
-    puts(ss);
-    free(ss);
-  }
+  handle_motd();
 
   syslog(LOG_INFO, "%s logged in on %s %s %s", pwd->pw_name,
-    ttyname(tty), hh ? "from" : "", hh ? TT.hostname : "");
+    ttyname(0), h_flag?"from":"", h_flag?TT.hostname:"");
 
-  // can't xexec here because name doesn't match argv[0]
-  snprintf(toybuf, sizeof(toybuf)-1, "-%s", basename_r(pwd->pw_shell));
-  toy_exec((char *[]){toybuf, 0});
-  execl(pwd->pw_shell, toybuf, NULL);
-  error_exit("Failed to spawn shell");
+  spawn_shell(pwd->pw_shell);
 }
old mode 100644 (file)
new mode 100755 (executable)
index 077ce75..c9b22ab
@@ -37,7 +37,7 @@ GLOBALS(
   FILE *db;
 )
 
-static int do_lspci(struct dirtree *new)
+int do_lspci(struct dirtree *new)
 {
   char *p = toybuf, *vendor = toybuf+9, *device = toybuf+18,
        driver[256], *vbig = 0, *dbig = 0, **fields;
old mode 100644 (file)
new mode 100755 (executable)
index a82ff7c..c16585a
@@ -40,6 +40,7 @@ void nbd_client_main(void)
 {
   int sock = -1, nbd, flags;
   unsigned long timeout = 0;
+  struct addrinfo *addr, *p;
   char *host=toys.optargs[0], *port=toys.optargs[1], *device=toys.optargs[2];
   uint64_t devsize;
 
@@ -48,10 +49,23 @@ void nbd_client_main(void)
   nbd = xopen(device, O_RDWR);
   for (;;) {
     int temp;
+    struct addrinfo hints;
 
     // Find and connect to server
 
-    sock = xconnect(host, port, AF_UNSPEC, SOCK_STREAM, 0, 0);
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = PF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    if (getaddrinfo(host, port, &hints, &addr)) addr = 0;
+    for (p = addr; p; p = p->ai_next) {
+      sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+      if (-1 != connect(sock, p->ai_addr, p->ai_addrlen)) break;
+      close(sock);
+    }
+    freeaddrinfo(addr);
+
+    if (!p) perror_exit("%s:%s", host, port);
+
     temp = 1;
     setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &temp, sizeof(int));
 
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 1e8f5e9..a135888
@@ -2,7 +2,7 @@
  *
  * Copyright 2013 Elie De Brauwer <eliedebrauwer@gmail.com>
 
-USE_REBOOT(NEWTOY(reboot, "fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
+USE_REBOOT(NEWTOY(reboot, "n", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_REBOOT(OLDTOY(halt, reboot, TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_REBOOT(OLDTOY(poweroff, reboot, TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 
@@ -10,11 +10,10 @@ config REBOOT
   bool "reboot"
   default y
   help
-    usage: reboot/halt/poweroff [-fn]
+    usage: reboot/halt/poweroff [-n]
 
     Restart, halt or powerdown the system.
 
-    -f Don't signal init
     -n Don't sync before stopping the system.
 */
 
@@ -24,12 +23,9 @@ config REBOOT
 
 void reboot_main(void)
 {
-  int types[] = {RB_AUTOBOOT, RB_HALT_SYSTEM, RB_POWER_OFF},
-      sigs[] = {SIGINT, SIGUSR1, SIGUSR2}, idx;
+  int types[] = {RB_AUTOBOOT, RB_HALT_SYSTEM, RB_POWER_OFF};
 
   if (!(toys.optflags & FLAG_n)) sync();
 
-  idx = stridx("hp", *toys.which->name)+1;
-  if (toys.optflags & FLAG_f) toys.exitval = reboot(types[idx]);
-  else toys.exitval = kill(1, sigs[idx]);
+  toys.exitval = reboot(types[stridx("hp", *toys.which->name)+1]);
 }
old mode 100644 (file)
new mode 100755 (executable)
index 4cf7214..b5720a3
@@ -15,7 +15,7 @@ config REV
 
 #include "toys.h"
 
-static void do_rev(int fd, char *name)
+void do_rev(int fd, char *name)
 {
   char *c;
 
index b1355a5..d6db44d 100644 (file)
@@ -15,12 +15,6 @@ config STAT
     -f display filesystem status instead of file status
     -c Output specified FORMAT string instead of default
 
-    The valid format escape sequences for filesystems:
-    %a  Available blocks    |%b  Total blocks       |%c  Total inodes
-    %d  Free inodes         |%f  Free blocks        |%i  File system ID
-    %l  Max filename length |%n  File name          |%s  Fragment size
-    %S  Best transfer size  |%t  File system type   |%T  Type in human readable form
-
     The valid format escape sequences for files:
     %a  Access bits (octal) |%A  Access bits (flags)|%b  Blocks allocated
     %B  Bytes per block     |%d  Device ID (dec)    |%D  Device ID (hex)
@@ -31,14 +25,11 @@ config STAT
     %x  Access time         |%X  Access unix time   |%y  File write time
     %Y  File write unix time|%z  Dir change time    |%Z  Dir change unix time
 
-config STAT_C
-  bool
-  default y
-  depends on STAT && !TOYBOX_LSM_NONE
-  help
-    usage: stat
-
-    %C  Security context
+    The valid format escape sequences for filesystems:
+    %a  Available blocks    |%b  Total blocks       |%c  Total inodes
+    %d  Free inodes         |%f  Free blocks        |%i  File system ID
+    %l  Max filename length |%n  File name          |%s  Fragment size
+    %S  Best transfer size  |%t  File system type
 */
 
 #define FOR_stat
@@ -55,35 +46,6 @@ GLOBALS(
   struct group *group_name;
 )
 
-static char* ftype_to_string(uint64_t ftype)
-{
-  switch (ftype) {
-    case 0xADFF: return "affs";
-    case 0x5346544e: return "ntfs";
-       case 0x1Cd1: return "devpts";
-    case 0x137D: return "ext";
-    case 0xEF51: return "ext2";
-    case 0xEF53: return "ext2/ext3";
-    case 0x1BADFACE: return "bfs";
-    case 0x9123683E: return "btrfs";
-    case 0x28cd3d45: return "cramfs";
-    case 0x3153464a: return "jfs";
-    case 0x7275: return "romfs";
-       case 0x01021994: return "tmpfs";
-       case 0x3434: return "nilfs";
-       case 0x6969: return "nfs";
-       case 0x9fa0: return "proc";
-       case 0x534F434B: return "sockfs";
-       case 0x62656572: return "sysfs";
-       case 0x517B: return "smb";
-       case 0x4d44: return "msdos";
-       case 0x4006: return "fat";
-    case 0x43415d53: return "smackfs";
-    case 0x73717368: return "squashfs";
-    default: return "unknown";
-  }
-}
-
 
 // Note: the atime, mtime, and ctime fields in struct stat are the start
 // of embedded struct timespec, but posix won't let them use that
@@ -108,13 +70,6 @@ static void print_stat(char type)
     xprintf("%s", str);
   } else if (type == 'b') xprintf("%llu", stat->st_blocks);
   else if (type == 'B') xprintf("%lu", stat->st_blksize);
-  else if (CFG_STAT_C && type == 'C') {
-    char *label = NULL;
-       if ((lsm_lget_context(*toys.optargs, (char **)&label) > 0) && label) {
-      xprintf("%s", label);
-         free(label);
-       }
-  }
   else if (type == 'd') xprintf("%ldd", stat->st_dev);
   else if (type == 'D') xprintf("%llxh", stat->st_dev);
   else if (type == 'f') xprintf("%lx", stat->st_mode);
@@ -158,7 +113,6 @@ static void print_statfs(char type) {
   else if (type == 'f') xprintf("%llu", statfs->f_bfree);
   else if (type == 'l') xprintf("%ld", statfs->f_namelen);
   else if (type == 't') xprintf("%lx", statfs->f_type);
-  else if (type == 'T') xprintf("%s", ftype_to_string(statfs->f_type));
   else if (type == 'i')
     xprintf("%08x%08x", statfs->f_fsid.__val[0], statfs->f_fsid.__val[1]);
   else if (type == 's') xprintf("%d", statfs->f_frsize);
@@ -170,7 +124,7 @@ void stat_main(void)
 {
   int flagf = toys.optflags & FLAG_f;
   char *format = flagf
-    ? "  File: \"%n\"\n    ID: %i Namelen: %l    Type: %T\n"
+    ? "  File: \"%n\"\n    ID: %i Namelen: %l    Type: %t\n"
       "Block Size: %s    Fundamental block size: %S\n"
       "Blocks: Total: %b\tFree: %f\tAvailable: %a\n"
       "Inodes: Total: %c\tFree: %d"
old mode 100644 (file)
new mode 100755 (executable)
index acbae2b..0861c70
@@ -67,13 +67,8 @@ void switch_root_main(void)
   }
   TT.rootdev=st2.st_dev;
 
-  // trim any / characters from the init cmdline, as we want to test it with
-  // stat(), relative to newroot. *cmdline is also used below, but by that
-  // point we are in the chroot, so a relative path is still OK.
-  while (**cmdline == '/') (*cmdline)++;
-
   // init program must exist and be an executable file
-  if (stat(*cmdline, &st1) || !S_ISREG(st1.st_mode) || !(st1.st_mode&0100)) {
+  if (stat("init", &st1) || !S_ISREG(st1.st_mode) || !(st1.st_mode&0100)) {
     error_msg("bad init");
     goto panic;
   }
@@ -86,24 +81,6 @@ void switch_root_main(void)
   // Ok, enough safety checks: wipe root partition.
   dirtree_read("/", del_node);
 
-  // Fix the appearance of the mount table in the newroot chroot
-  if (mount(".", "/", NULL, MS_MOVE, NULL)) {
-    perror_msg("mount");
-    goto panic;
-  }
-
-  // Enter the new root before starting init
-  if (chroot(".")) {
-    perror_msg("chroot");
-    goto panic;
-  }
-
-  // Make sure cwd does not point outside of the chroot
-  if (chdir("/")) {
-    perror_msg("chdir");
-    goto panic;
-  }
-
   if (TT.console) {
     int i;
     for (i=0; i<3; i++) if (console != i) dup2(console, i);
old mode 100644 (file)
new mode 100755 (executable)
index d5f72fd..538d1b0
@@ -15,7 +15,7 @@ config TAC
 
 #include "toys.h"
 
-static void do_tac(int fd, char *name)
+void do_tac(int fd, char *name)
 {
   struct arg_list *list = NULL;
   char *c;
old mode 100644 (file)
new mode 100755 (executable)
index 4ade5f1..2851923
@@ -120,7 +120,7 @@ void taskset_main(void)
   }
 }
 
-static int do_nproc(struct dirtree *new)
+int do_nproc(struct dirtree *new)
 {
   if (!new->parent) return DIRTREE_RECURSE;
   if (!strncmp(new->name, "cpu", 3) && isdigit(new->name[3])) TT.nproc++;
old mode 100644 (file)
new mode 100755 (executable)
index 9a38e45..c11e46b
@@ -39,7 +39,7 @@ struct vmstat_proc {
 
 // All the elements of vmstat_proc are the same size, so we can populate it as
 // a big array, then read the elements back out by name
-static void get_vmstat_proc(struct vmstat_proc *vmstat_proc)
+void get_vmstat_proc(struct vmstat_proc *vmstat_proc)
 {
   char *vmstuff[] = { "/proc/stat", "cpu ", 0, 0, 0, 0, 0, 0,
     "intr ", "ctxt ", "procs_running ", "procs_blocked ", "/proc/meminfo",
old mode 100644 (file)
new mode 100755 (executable)
index 366d3c5..3449104
@@ -133,9 +133,9 @@ static void summary()
   //out to STDERR
   fprintf(stderr,"%llu+%llu records in\n%llu+%llu records out\n", st.in_full, st.in_part,
       st.out_full, st.out_part);
-  human_readable(toybuf, st.bytes, HR_SPACE|HR_B);
+  human_readable(toybuf, st.bytes);
   fprintf(stderr, "%llu bytes (%s) copied, ",st.bytes, toybuf);
-  human_readable(toybuf, st.bytes/seconds, HR_SPACE|HR_B);
+  human_readable(toybuf, st.bytes/seconds);
   fprintf(stderr, "%f s, %s/s\n", seconds, toybuf);
 }
 
old mode 100644 (file)
new mode 100755 (executable)
index d9e78ff..529c1b9
@@ -348,7 +348,6 @@ static void halt_poweroff_reboot_handler(int sig_no)
       reboot_magic_no=RB_POWER_OFF;
       break;
     case SIGTERM:  
-    case SIGINT:
       error_msg("Requesting system reboot");
       reboot_magic_no=RB_AUTOBOOT;
       break;
@@ -416,7 +415,7 @@ static void pause_handler(int sig_no)
 
   errno_backup = errno;
   signal_backup = caught_signal;
-  xsignal(SIGCONT, catch_signal);
+  signal(SIGCONT, catch_signal);
 
   while(1) {
     if (caught_signal == SIGCONT) break;
@@ -461,11 +460,10 @@ void init_main(void)
   putenv("USER=root");
 
   inittab_parsing();  
-  xsignal(SIGUSR1, halt_poweroff_reboot_handler);//halt
-  xsignal(SIGUSR2, halt_poweroff_reboot_handler);//poweroff
-  xsignal(SIGTERM, halt_poweroff_reboot_handler);//reboot
-  xsignal(SIGINT, halt_poweroff_reboot_handler);//reboot
-  xsignal(SIGQUIT, restart_init_handler);//restart init
+  signal(SIGUSR1, halt_poweroff_reboot_handler);//halt
+  signal(SIGUSR2, halt_poweroff_reboot_handler);//poweroff
+  signal(SIGTERM, halt_poweroff_reboot_handler);//reboot
+  signal(SIGQUIT, restart_init_handler);//restart init
   memset(&sig_act, 0, sizeof(sig_act));
   sigfillset(&sig_act.sa_mask);
   sigdelset(&sig_act.sa_mask, SIGCONT);
@@ -473,6 +471,7 @@ void init_main(void)
   sigaction(SIGTSTP, &sig_act, NULL);
   memset(&sig_act, 0, sizeof(sig_act));
   sig_act.sa_handler = catch_signal;
+  sigaction(SIGINT, &sig_act, NULL);
   sigaction(SIGHUP, &sig_act, NULL);  
   run_action_from_list(SYSINIT);
   check_if_pending_signals();
old mode 100644 (file)
new mode 100755 (executable)
index a13a53d..0c49633
@@ -35,7 +35,7 @@ config MDEV_CONF
 static void make_device(char *path)
 {
   char *device_name = NULL, *s, *temp;
-  int major = 0, minor = 0, type, len, fd;
+  int major, minor, type, len, fd;
   int mode = 0660;
   uid_t uid = 0;
   gid_t gid = 0;
@@ -46,21 +46,24 @@ static void make_device(char *path)
     temp = strrchr(path, '/');
     fd = open(path, O_RDONLY);
     *temp=0;
-    len = read(fd, toybuf, 64);
+    temp = toybuf;
+    len = read(fd, temp, 64);
     close(fd);
     if (len<1) return;
-    toybuf[len] = 0;
+    temp[len] = 0;
 
     // Determine device type, major and minor
 
     type = path[5]=='c' ? S_IFCHR : S_IFBLK;
-    sscanf(toybuf, "%u:%u", &major, &minor);
+    major = minor = 0;
+    sscanf(temp, "%u:%u", &major, &minor);
   } else {
     // if (!path), do hotplug
 
     if (!(temp = getenv("SUBSYSTEM")))
       return;
     type = strcmp(temp, "block") ? S_IFCHR : S_IFBLK;
+    major = minor = 0;
     if (!(temp = getenv("MAJOR")))
       return;
     sscanf(temp, "%u", &major);
@@ -71,15 +74,11 @@ static void make_device(char *path)
     device_name = getenv("DEVNAME");
     if (!path)
       return;
+    temp = toybuf;
   }
   if (!device_name)
     device_name = strrchr(path, '/') + 1;
 
-  // as in linux/drivers/base/core.c, device_get_devnode()
-  while ((temp = strchr(device_name, '!'))) {
-    *temp = '/';
-  }
-
   // If we have a config file, look up permissions for this device
 
   if (CFG_MDEV_CONF) {
@@ -186,22 +185,22 @@ found_device:
     }
   }
 
-  sprintf(toybuf, "/dev/%s", device_name);
+  sprintf(temp, "/dev/%s", device_name);
 
-  if ((temp=getenv("ACTION")) && !strcmp(temp, "remove")) {
-    unlink(toybuf);
+  if (getenv("ACTION") && !strcmp(getenv("ACTION"), "remove")) {
+    unlink(temp);
     return;
   }
 
   if (strchr(device_name, '/'))
-    mkpathat(AT_FDCWD, toybuf, 0, 2);
-  if (mknod(toybuf, mode | type, makedev(major, minor)) && errno != EEXIST)
-    perror_exit("mknod %s failed", toybuf);
+    mkpathat(AT_FDCWD, temp, 0, 2);
+  if (mknod(temp, mode | type, makedev(major, minor)) && errno != EEXIST)
+    perror_exit("mknod %s failed", temp);
 
  
-  if (type == S_IFBLK) close(open(toybuf, O_RDONLY)); // scan for partitions
+  if (type == S_IFBLK) close(open(temp, O_RDONLY)); // scan for partitions
 
-  if (CFG_MDEV_CONF) mode=chown(toybuf, uid, gid);
+  if (CFG_MDEV_CONF) mode=chown(temp, uid, gid);
 }
 
 static int callback(struct dirtree *node)
old mode 100644 (file)
new mode 100755 (executable)
index 07c53fc..5431cb3
@@ -65,12 +65,14 @@ struct module_s {
 static char *path2mod(char *file, char *mod)
 {
   int i;
-  char *from;
+  char *from, *lslash;
 
   if (!file) return NULL;
   if (!mod) mod = xmalloc(MODNAME_LEN);
        
-  from = basename_r(file);
+  lslash = strrchr(file, '/');
+  if (!lslash || (lslash == file && !lslash[1])) from = file;
+  else from = lslash + 1;
   
   for (i = 0; i < (MODNAME_LEN-1) && from[i] && from[i] != '.'; i++)
     mod[i] = (from[i] == '-') ? '_' : from[i];
@@ -275,8 +277,7 @@ static int config_action(struct dirtree *node)
       get_mod(tokens[1], 1)->flags |= MOD_BLACKLIST;
     else if (!strcmp(tokens[0], "install")) continue;
     else if (!strcmp(tokens[0], "remove")) continue;
-    else if (toys.optflags & FLAG_q)
-      error_msg("Invalid option %s found in file %s", tokens[0], filename);
+    else error_msg("Invalid option %s found in file %s", tokens[0], filename);
   }
   fclose(fc);
   free(filename);
@@ -380,6 +381,7 @@ static int ins_mod(char *modules, char *flags)
   }
   res = syscall(__NR_init_module, buf, len, toybuf);
   if (CFG_TOYBOX_FREE && buf != toybuf) free(buf);
+  if (res) perror_exit("failed to load %s ", toys.optargs[0]);
   return res;
 }
 
@@ -426,7 +428,7 @@ static int go_probe(struct module_s *m)
   int rc = 0, first = 1;
 
   if (!(m->flags & MOD_FNDDEPMOD)) {
-    if (!(toys.optflags & FLAG_q))
+    if (!(toys.optflags & FLAG_s))
       error_msg("module %s not found in modules.dep", m->name);
     return -ENOENT;
   }
index fd0a355..450bd72 100644 (file)
@@ -5,14 +5,14 @@
  *
  * No Standard
 
-USE_SYSLOGD(NEWTOY(syslogd,">0l#<1>8=8R:b#<0>99=1B#<0>99=0s#<0=2000m#<0>71582787=20O:p:f:a:nSKLD", TOYFLAG_SBIN|TOYFLAG_STAYROOT))
+USE_SYSLOGD(NEWTOY(syslogd,">0l#<1>8=8R:b#<0>99=1s#<0=200m#<0>71582787=20O:p:f:a:nSKLD", TOYFLAG_SBIN|TOYFLAG_STAYROOT))
 
 config SYSLOGD
   bool "syslogd"
-  default y
+  default n
   help
   usage: syslogd  [-a socket] [-O logfile] [-f config file] [-m interval]
-                  [-p socket] [-s SIZE] [-b N] [-B N][-R HOST] [-l N] [-nSLKD]
+                  [-p socket] [-s SIZE] [-b N] [-R HOST] [-l N] [-nSLKD]
 
   System logging utility
 
@@ -27,7 +27,6 @@ config SYSLOGD
   -L      Log locally and via network (default is network only if -R)"
   -s SIZE Max size (KB) before rotation (default:200KB, 0=off)
   -b N    rotated logs to keep (default:1, max=99, 0=purge)
-  -B N      Set number of logs to keep logs in memory buffer before write (default:0, max=99, 0=purge)
   -K      Log to kernel printk buffer (use dmesg to read it)
   -l N    Log only messages more urgent than prio(default:8 max:8 min:1)
   -D      Drop duplicates
@@ -55,12 +54,6 @@ struct logfile {
   struct sockaddr_in saddr;
 };
 
-// Log buffer
-struct logbuffer {
-  int len;
-  char buf[1024];
-};
-
 GLOBALS(
   char *socket;
   char *config_file;
@@ -68,7 +61,6 @@ GLOBALS(
   char *logfile;
   long interval;
   long rot_size;
-  long buf_count;
   long rot_count;
   char *remote_log;
   long log_prio;
@@ -286,9 +278,7 @@ static void open_logfiles(void)
 //write to file with rotation
 static int write_rotate(struct logfile *tf, int len)
 {
-  int size, isreg, idx;
-  static int buf_idx = 0;
-  static struct logbuffer buffer[100];
+  int size, isreg;
   struct stat statf;
   isreg = (!fstat(tf->logfd, &statf) && S_ISREG(statf.st_mode));
   size = statf.st_size;
@@ -318,18 +308,6 @@ static int write_rotate(struct logfile *tf, int len)
       ftruncate(tf->logfd, 0);
     }
   }
-  if (TT.buf_count && (toys.optflags & FLAG_B)) {
-    if (buf_idx < TT.buf_count) {
-      memcpy(buffer[buf_idx].buf, toybuf, len);
-         buffer[buf_idx].buf[len + 1] = '\0';
-         buffer[buf_idx].len = len;
-         buf_idx++;
-         return len;
-       } else {
-         for (idx = 0; idx < TT.buf_count; idx++) write(tf->logfd, buffer[idx].buf, buffer[idx].len);
-         buf_idx = 0;
-       }
-  }
   return write(tf->logfd, toybuf, len);
 }
 
old mode 100644 (file)
new mode 100755 (executable)
index dc3487a..f113cbb
@@ -48,6 +48,39 @@ GLOBALS(
 #define UF_ECHO     0x01
 #define UF_SGA      0x02
 
+/*
+ * creates a socket of family INET/INET6 and protocol TCP and connects
+ * it to HOST at PORT.
+ * if successful then returns SOCK othrwise error
+ */
+static int xconnect_inet_tcp(char *host, int port)
+{
+  int ret;
+  struct addrinfo *info, *rp;
+  char buf[32];
+
+  rp = xzalloc(sizeof(struct addrinfo));
+  rp->ai_family = AF_UNSPEC;
+  rp->ai_socktype = SOCK_STREAM;
+  rp->ai_protocol = IPPROTO_TCP;
+  sprintf(buf, "%d", port);
+
+  ret = getaddrinfo(host, buf, rp, &info);
+  if(ret || !info) perror_exit("BAD ADDRESS: can't find : %s ", host);
+  free(rp);
+
+  for (rp = info; rp; rp = rp->ai_next) 
+    if ( (rp->ai_family == AF_INET) || (rp->ai_family == AF_INET6)) break;
+
+  if (!rp) error_exit("Invalid IP %s", host);
+
+  ret = xsocket(rp->ai_family, SOCK_STREAM, IPPROTO_TCP);
+  if(connect(ret, rp->ai_addr, rp->ai_addrlen) == -1) perror_exit("connect");
+
+  freeaddrinfo(info);
+  return ret;
+}
+
 // sets terminal mode: LINE or CHARACTER based om internal stat.
 static char const es[] = "\r\nEscape character is ";
 static void set_mode(void)
@@ -102,7 +135,7 @@ static void handle_esc(void)
   char input;
 
   if(toys.signal && TT.term_ok) tcsetattr(0, TCSADRAIN, &TT.raw_term);
-  xwrite(1,"\r\nConsole escape. Commands are:\r\n\n"
+  write(1,"\r\nConsole escape. Commands are:\r\n\n"
       " l  go to line mode\r\n"
       " c  go to character mode\r\n"
       " z  suspend telnet\r\n"
@@ -145,7 +178,7 @@ static void handle_esc(void)
   default: break;
   }
 
-  xwrite(1, "continuing...\r\n", 15);
+  write(1, "continuing...\r\n", 15);
   if (toys.signal && TT.term_ok) tcsetattr(0, TCSADRAIN, &TT.def_term);
 
 ret:
@@ -259,7 +292,7 @@ static int read_server(int len)
     }
   } while (TT.pbuff < len);
 
-  if (i) xwrite(STDIN_FILENO, toybuf, i);
+  if (i) write(STDIN_FILENO, toybuf, i);
   return 0;
 }
 
@@ -281,19 +314,20 @@ static void write_server(int len)
     if (*c == IAC) toybuf[i++] = *c; /* IAC -> IAC IAC */
     else if (*c == '\r') toybuf[i++] = '\0'; /* CR -> CR NUL */
   }
-  if(i) xwrite(TT.sfd, toybuf, i);
+  if(i) write(TT.sfd, toybuf, i);
 }
 
 void telnet_main(void)
 {
-  char *port = "23";
   int set = 1, len;
   struct pollfd pfds[2];
 
+  TT.port = 23; //TELNET_PORT
   TT.win_width = 80; //columns
   TT.win_height = 24; //rows
 
-  if (toys.optc == 2) port = toys.optargs[1];
+  if(toys.optc == 2) TT.port = atoi(toys.optargs[1]);
+  if(TT.port <= 0 || TT.port > 65535) error_exit("bad PORT (1-65535)");
 
   TT.ttype = getenv("TERM");
   if(!TT.ttype) TT.ttype = "";
@@ -306,7 +340,7 @@ void telnet_main(void)
   }
   terminal_size(&TT.win_width, &TT.win_height);
 
-  TT.sfd = xconnect(*toys.optargs, port, 0, SOCK_STREAM, IPPROTO_TCP, 0);
+  TT.sfd = xconnect_inet_tcp(toys.optargs[0], TT.port);
   setsockopt(TT.sfd, SOL_SOCKET, SO_REUSEADDR, &set, sizeof(set));
   setsockopt(TT.sfd, SOL_SOCKET, SO_KEEPALIVE, &set, sizeof(set));
 
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/toys/pending/tftp.c b/toys/pending/tftp.c
deleted file mode 100644 (file)
index 60d5f17..0000000
+++ /dev/null
@@ -1,454 +0,0 @@
-/* tftp.c - TFTP client.
- *
- * Copyright 2012 Madhur Verma <mad.flexi@gmail.com>
- * Copyright 2015 Sameer Prakash Pradhan <sameer.p.pradhan@gmail.com>
- *
- * No Standard.
-
-USE_TFTP(NEWTOY(tftp, "<1b#<8>65464r:l:g|p|[!gp]", TOYFLAG_USR|TOYFLAG_BIN))
-
-config TFTP
-  bool "tftp"
-  default n
-  help
-    usage: tftp [OPTIONS] HOST [PORT]
-
-    Transfer file from/to tftp server.
-
-    -l FILE Local FILE
-    -r FILE Remote FILE
-    -g    Get file
-    -p    Put file
-    -b SIZE Transfer blocks of SIZE octets(8 <= SIZE <= 65464)
-*/
-#define FOR_tftp
-#include "toys.h"
-
-GLOBALS(
-  char *local_file;
-  char *remote_file;
-  long block_size;
-
-  struct sockaddr_storage inaddr;
-  int af;
-)
-
-#define TFTP_BLKSIZE    512
-#define TFTP_RETRIES    3
-#define TFTP_DATAHEADERSIZE 4
-#define TFTP_MAXPACKETSIZE  (TFTP_DATAHEADERSIZE + TFTP_BLKSIZE)
-#define TFTP_PACKETSIZE    TFTP_MAXPACKETSIZE
-#define TFTP_DATASIZE    (TFTP_PACKETSIZE-TFTP_DATAHEADERSIZE)
-#define TFTP_IOBUFSIZE    (TFTP_PACKETSIZE+8)
-
-#define TFTP_OP_RRQ      1  /* Read Request      RFC 1350, RFC 2090 */
-#define TFTP_OP_WRQ      2  /* Write Request     RFC 1350 */
-#define TFTP_OP_DATA    3  /* Data chunk      RFC 1350 */
-#define TFTP_OP_ACK      4  /* Acknowledgement     RFC 1350 */
-#define TFTP_OP_ERR      5  /* Error Message     RFC 1350 */
-#define TFTP_OP_OACK    6  /* Option acknowledgment RFC 2347 */
-
-#define TFTP_ER_ILLEGALOP  4  /* Illegal TFTP operation */
-#define TFTP_ER_UNKID    5  /* Unknown transfer ID */
-
-#define TFTP_ES_NOSUCHFILE  "File not found"
-#define TFTP_ES_ACCESS    "Access violation"
-#define TFTP_ES_FULL    "Disk full or allocation exceeded"
-#define TFTP_ES_ILLEGALOP  "Illegal TFTP operation"
-#define TFTP_ES_UNKID    "Unknown transfer ID"
-#define TFTP_ES_EXISTS    "File already exists"
-#define TFTP_ES_UNKUSER    "No such user"
-#define TFTP_ES_NEGOTIATE  "Terminate transfer due to option negotiation"
-
-// Initializes SERVER with ADDR and returns socket.
-static int init_tftp(struct sockaddr_storage *server)
-{
-  struct timeval to = { .tv_sec = 10, //Time out
-                        .tv_usec = 0 };
-  const int set = 1;
-  int port = 69, sd = xsocket(TT.af, SOCK_DGRAM, IPPROTO_UDP);
-
-  xsetsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (void *)&to, sizeof(struct timeval));
-  xsetsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (void *)&set, sizeof(set));
-
-  if(toys.optc == 2) port = atolx_range(toys.optargs[1], 1, 65535);
-  memset(server, 0, sizeof(struct sockaddr_storage));
-  if (TT.af == AF_INET6) {
-      ((struct sockaddr_in6 *)server)->sin6_family = AF_INET6;
-      ((struct sockaddr_in6 *)server)->sin6_addr =
-        ((struct sockaddr_in6 *)&TT.inaddr)->sin6_addr;
-      ((struct sockaddr_in6 *)server)->sin6_port = htons(port);
-  }
-  else {
-      ((struct sockaddr_in *)server)->sin_family = AF_INET;
-      ((struct sockaddr_in *)server)->sin_addr.s_addr =
-        ((struct sockaddr_in *)&TT.inaddr)->sin_addr.s_addr;
-      ((struct sockaddr_in *)server)->sin_port = htons(port);
-  }
-  return sd;
-}
-
-/*
- * Makes a request packet in BUFFER with OPCODE and file PATH of MODE
- * and returns length of packet.
- */
-static int mkpkt_request(uint8_t *buffer, int opcode, char *path, int mode)
-{
-  buffer[0] = opcode >> 8;
-  buffer[1] = opcode & 0xff;
-  if(strlen(path) > TFTP_BLKSIZE) error_exit("path too long");
-  return sprintf((char*) &buffer[2], "%s%c%s", path, 0, 
-    (mode ? "octet" : "netascii")) + 3;
-}
-
-/*
- * Makes an acknowledgement packet in BUFFER of BLOCNO
- * and returns packet length.
- */
-static int mkpkt_ack(uint8_t *buffer, uint16_t blockno)
-{
-  buffer[0] = TFTP_OP_ACK >> 8;
-  buffer[1] = TFTP_OP_ACK & 0xff;
-  buffer[2] = blockno >> 8;
-  buffer[3] = blockno & 0xff;
-  return 4;
-}
-
-/*
- * Makes an error packet in BUFFER with ERRORCODE and ERRORMSG.
- * and returns packet length.
- */
-static int mkpkt_err(uint8_t *buffer, uint16_t errorcode, char *errormsg)
-{
-  buffer[0] = TFTP_OP_ERR >> 8;
-  buffer[1] = TFTP_OP_ERR & 0xff;
-  buffer[2] = errorcode >> 8;
-  buffer[3] = errorcode & 0xff;
-  strcpy((char*) &buffer[4], errormsg);
-  return strlen(errormsg) + 5;
-}
-
-/*
- * Recieves data from server in BUFF with socket SD and updates FROM
- * and returns read length.
- */
-static ssize_t read_server(int sd, void *buf, size_t len,
-  struct sockaddr_storage *from)
-{
-  socklen_t alen;
-  ssize_t nb;
-  
-  for (;;) {
-    memset(buf, 0, len);
-    alen = sizeof(struct sockaddr_storage);
-    nb = recvfrom(sd, buf, len, 0, (struct sockaddr *) from, &alen);
-    if (nb < 0) {
-      if (errno == EAGAIN) {
-        perror_msg("server read timed out");
-        return nb;
-      }else if (errno != EINTR) {
-        perror_msg("server read failed");
-        return nb;
-      }
-    }else return nb;
-  }
-  return nb;
-}
-
-/*
- * sends data to server TO from BUFF of length LEN through socket SD
- * and returns successfully send bytes number.
- */
-static ssize_t write_server(int sd, void *buf, size_t len,
-  struct sockaddr_storage *to)
-{
-  ssize_t nb;
-  
-  for (;;) {
-    nb = sendto(sd, buf, len, 0, (struct sockaddr *)to,
-            sizeof(struct sockaddr_storage));
-    if (nb < 0) {
-      if (errno != EINTR) {
-        perror_msg("server write failed");
-        return nb;
-      }
-    } else return nb;
-  }
-  return nb;
-}
-
-// checks packet for data and updates block no
-static inline int check_data( uint8_t *packet, uint16_t *opcode, 
-  uint16_t *blockno)
-{
-  *opcode = (uint16_t) packet[0] << 8 | (uint16_t) packet[1];
-  if (*opcode == TFTP_OP_DATA) {
-    *blockno = (uint16_t) packet[2] << 8 | (uint16_t) packet[3];
-    return 0;
-  }
-  return -1;
-}
-
-// Makes data packet through FD from file OFFSET in buffer PACKET of BLOCKNO
-static int mkpkt_data(int fd, off_t offset, uint8_t *packet, uint16_t blockno)
-{
-  off_t tmp;
-  int nbytesread;
-
-  packet[0] = TFTP_OP_DATA >> 8;
-  packet[1] = TFTP_OP_DATA & 0xff;
-  packet[2] = blockno >> 8;
-  packet[3] = blockno & 0xff;
-  tmp = lseek(fd, offset, SEEK_SET);
-  if (tmp == (off_t) -1) {
-    perror_msg("lseek failed");
-    return -1;
-  }
-  nbytesread = readall(fd, &packet[TFTP_DATAHEADERSIZE], TFTP_DATASIZE);
-  if (nbytesread < 0) return -1;
-  return nbytesread + TFTP_DATAHEADERSIZE;
-}
-
-// Receives ACK responses from server and updates blockno
-static int read_ack(int sd, uint8_t *packet, struct sockaddr_storage *server,
-  uint16_t *port, uint16_t *blockno)
-{
-  struct sockaddr_storage from;
-  ssize_t nbytes;
-  uint16_t opcode, rblockno;
-  int packetlen, retry;
-
-  for (retry = 0; retry < TFTP_RETRIES; retry++) {
-    for (;;) {
-      nbytes = read_server(sd, packet, TFTP_IOBUFSIZE, &from);
-      if (nbytes < 4) { // Ack headersize = 4
-        if (nbytes == 0) error_msg("Connection lost.");
-        else if (nbytes > 0) error_msg("Short packet: %d bytes", nbytes);
-        else error_msg("Server read ACK failure.");
-        break;
-      } else {
-        if (!*port) {
-          *port = ((struct sockaddr_in *)&from)->sin_port;
-          ((struct sockaddr_in *)server)->sin_port =
-                  ((struct sockaddr_in *)&from)->sin_port;
-        }
-        if (((struct sockaddr_in *)server)->sin_addr.s_addr !=
-                ((struct sockaddr_in *)&from)->sin_addr.s_addr) {
-          error_msg("Invalid address in DATA.");
-          continue;
-        }
-        if (*port != ((struct sockaddr_in *)server)->sin_port) {
-          error_msg("Invalid port in DATA.");
-          packetlen = mkpkt_err(packet, TFTP_ER_UNKID, TFTP_ES_UNKID);
-          (void) write_server(sd, packet, packetlen, server);
-          continue;
-        }
-        opcode = (uint16_t) packet[0] << 8 | (uint16_t) packet[1];
-        rblockno = (uint16_t) packet[2] << 8 | (uint16_t) packet[3];
-
-        if (opcode != TFTP_OP_ACK) {
-          error_msg("Bad opcode.");
-          if (opcode > 5) {
-            packetlen = mkpkt_err(packet, TFTP_ER_ILLEGALOP, TFTP_ES_ILLEGALOP);
-            (void) write_server(sd, packet, packetlen, server);
-          }
-          break;
-        }
-        if (blockno) *blockno = rblockno;
-        return 0;
-      }
-    }
-  }
-  error_msg("Timeout, Waiting for ACK.");
-  return -1;
-}
-
-// receives file from server.
-static int file_get(void)
-{
-  struct sockaddr_storage server, from;
-  uint8_t *packet;
-  uint16_t blockno = 0, opcode, rblockno = 0;
-  int len, sd, fd, retry, nbytesrecvd = 0, ndatabytes, ret, result = -1;
-
-  sd = init_tftp(&server);
-
-  packet = (uint8_t*) xzalloc(TFTP_IOBUFSIZE);
-  fd = xcreate(TT.local_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
-
-  len = mkpkt_request(packet, TFTP_OP_RRQ, TT.remote_file, 1);
-  ret = write_server(sd, packet, len, &server);
-  if (ret != len){
-    unlink(TT.local_file);
-    goto errout_with_sd;
-  }
-  if (TT.af == AF_INET6) ((struct sockaddr_in6 *)&server)->sin6_port = 0;
-  else ((struct sockaddr_in *)&server)->sin_port = 0;
-
-  do {
-    blockno++;
-    for (retry = 0 ; retry < TFTP_RETRIES; retry++) {
-      nbytesrecvd = read_server(sd, packet, TFTP_IOBUFSIZE, &from);
-      if (nbytesrecvd > 0) {
-        if ( ((TT.af == AF_INET) &&
-                memcmp(&((struct sockaddr_in *)&server)->sin_addr,
-                &((struct sockaddr_in *)&from)->sin_addr,
-                sizeof(struct in_addr))) ||
-             ((TT.af == AF_INET6) &&
-                memcmp(&((struct sockaddr_in6 *)&server)->sin6_addr,
-                &((struct sockaddr_in6 *)&from)->sin6_addr,
-                sizeof(struct in6_addr)))) {
-          error_msg("Invalid address in DATA.");
-          retry--;
-          continue;
-        }
-        if ( ((TT.af == AF_INET) && ((struct sockaddr_in *)&server)->sin_port
-                && (((struct sockaddr_in *)&server)->sin_port !=
-                ((struct sockaddr_in *)&from)->sin_port)) ||
-             ((TT.af == AF_INET6) && ((struct sockaddr_in6 *)&server)->sin6_port
-                && (((struct sockaddr_in6 *)&server)->sin6_port !=
-                ((struct sockaddr_in6 *)&from)->sin6_port))) {
-          error_msg("Invalid port in DATA.");
-          len = mkpkt_err(packet, TFTP_ER_UNKID, TFTP_ES_UNKID);
-          ret = write_server(sd, packet, len, &from);
-          retry--;
-          continue;
-        }
-        if (nbytesrecvd < TFTP_DATAHEADERSIZE) {
-          error_msg("Tiny data packet ignored.");
-          continue;
-        }
-        if (check_data(packet, &opcode, &rblockno) != 0
-            || blockno != rblockno) {
-
-        if (opcode == TFTP_OP_ERR) {
-          char *message = "DATA Check failure.";
-            char *arr[] = {TFTP_ES_NOSUCHFILE, TFTP_ES_ACCESS,
-              TFTP_ES_FULL, TFTP_ES_ILLEGALOP,
-              TFTP_ES_UNKID, TFTP_ES_EXISTS,
-              TFTP_ES_UNKUSER, TFTP_ES_NEGOTIATE};
-            if (rblockno && (rblockno < 9)) message = arr[rblockno - 1];
-            error_msg(message);
-        }
-        if (opcode > 5) {
-          len = mkpkt_err(packet, TFTP_ER_ILLEGALOP, TFTP_ES_ILLEGALOP);
-          ret = write_server(sd, packet, len, &from);
-        }
-        continue;
-        }
-        if ((TT.af == AF_INET6) && !((struct sockaddr_in6 *)&server)->sin6_port)
-          ((struct sockaddr_in6 *)&server)->sin6_port =
-            ((struct sockaddr_in6 *)&from)->sin6_port;
-        else if ((TT.af == AF_INET) && !((struct sockaddr_in *)&server)->sin_port)
-          ((struct sockaddr_in *)&server)->sin_port =
-            ((struct sockaddr_in *)&from)->sin_port;
-        break;
-      }
-    }
-    if (retry == TFTP_RETRIES) {
-      error_msg("Retry limit exceeded.");
-      unlink(TT.local_file);
-      goto errout_with_sd;
-    }
-    ndatabytes = nbytesrecvd - TFTP_DATAHEADERSIZE;
-    if (writeall(fd, packet + TFTP_DATAHEADERSIZE, ndatabytes) < 0){
-      unlink(TT.local_file);
-      goto errout_with_sd;
-    }
-    len = mkpkt_ack(packet, blockno);
-    ret = write_server(sd, packet, len, &server);
-    if (ret != len){
-      unlink(TT.local_file);
-      goto errout_with_sd;
-    }
-  } while (ndatabytes >= TFTP_DATASIZE);
-
-  result = 0;
-
-errout_with_sd: xclose(sd);
-  free(packet);
-  return result;
-}
-
-// Sends file to server.
-int file_put(void)
-{
-  struct sockaddr_storage server;
-  uint8_t *packet;
-  off_t offset = 0;
-  uint16_t blockno = 1, rblockno, port = 0;
-  int packetlen, sd, fd, retry = 0, ret, result = -1;
-
-  sd = init_tftp(&server);
-  packet = (uint8_t*)xzalloc(TFTP_IOBUFSIZE);
-  fd = xopen(TT.local_file, O_RDONLY);
-
-  for (;;) {  //first loop for request send and confirmation from server.
-    packetlen = mkpkt_request(packet, TFTP_OP_WRQ, TT.remote_file, 1);
-    ret = write_server(sd, packet, packetlen, &server);
-    if (ret != packetlen) goto errout_with_sd;
-    if (read_ack(sd, packet, &server, &port, NULL) == 0) break;
-    if (++retry > TFTP_RETRIES) {
-      error_msg("Retry count exceeded.");
-      goto errout_with_sd;
-    }
-  }
-  for (;;) {  // loop for data sending and receving ack from server.
-    packetlen = mkpkt_data(fd, offset, packet, blockno);
-    if (packetlen < 0) goto errout_with_sd;
-
-    ret = write_server(sd, packet, packetlen, &server);
-    if (ret != packetlen) goto errout_with_sd;
-
-    if (read_ack(sd, packet, &server, &port, &rblockno) == 0) {
-      if (rblockno == blockno) {
-        if (packetlen < TFTP_PACKETSIZE) break;
-        blockno++;
-        offset += TFTP_DATASIZE;
-        retry = 0;
-        continue;
-      }
-    }
-    if (++retry > TFTP_RETRIES) {
-      error_msg("Retry count exceeded.");
-      goto errout_with_sd;
-    }
-  }
-  result = 0;
-
-errout_with_sd: close(sd);
-  free(packet);
-  return result;
-}
-
-void tftp_main(void)
-{
-  struct addrinfo *info, rp, *res=0;
-  int ret;
-
-  if (toys.optflags & FLAG_r) {
-    if (!(toys.optflags & FLAG_l)) {
-      char *slash = strrchr(TT.remote_file, '/');
-      TT.local_file = (slash) ? slash + 1 : TT.remote_file;
-    }
-  } else if (toys.optflags & FLAG_l) TT.remote_file = TT.local_file;
-  else error_exit("Please provide some files.");
-
-  memset(&rp, 0, sizeof(rp));
-  rp.ai_family = AF_UNSPEC;
-  rp.ai_socktype = SOCK_STREAM;
-  ret = getaddrinfo(toys.optargs[0], toys.optargs[1], &rp, &info);
-  if (!ret) {
-    for (res = info; res; res = res->ai_next)
-    if ( (res->ai_family == AF_INET) || (res->ai_family == AF_INET6)) break;
-  }
-  if (!res)
-    error_exit("bad address '%s' : %s", toys.optargs[0], gai_strerror(ret));
-  TT.af = info->ai_family;
-
-  memcpy((void *)&TT.inaddr, info->ai_addr, info->ai_addrlen);
-  freeaddrinfo(info);
-
-  if (toys.optflags & FLAG_g) file_get();
-  if (toys.optflags & FLAG_p) file_put();
-}
old mode 100644 (file)
new mode 100755 (executable)
index bd3afad..bb476df
@@ -64,6 +64,14 @@ static char *calstrings(char *buf, struct tm *tm)
   return buf;
 }
 
+void xcheckrange(long val, long low, long high)
+{
+  char *err = "%ld %s than %ld";
+
+  if (val < low) error_exit(err, val, "less", low);
+  if (val > high) error_exit(err, val, "greater", high);
+}
+
 // Worst case scenario toybuf usage: sizeof(struct tm) plus 21 bytes/line
 // plus 8 lines/month plus 12 months, comes to a bit over 2k of our 4k buffer.
 
@@ -78,12 +86,12 @@ void cal_main(void)
     buf += sizeof(struct tm);
 
     // Last argument is year, one before that (if any) is month.
-    tm->tm_year = atolx_range(toys.optargs[--toys.optc], 1, 9999);
+    xcheckrange(tm->tm_year = atol(toys.optargs[--toys.optc]),1,9999);
     tm->tm_year -= 1900;
     tm->tm_mday = 1;
     tm->tm_hour = 12;  // noon to avoid timezone weirdness
     if (toys.optc) {
-      tm->tm_mon = atolx_range(toys.optargs[--toys.optc], 1, 12);
+      xcheckrange(tm->tm_mon = atol(toys.optargs[--toys.optc]),1,12);
       tm->tm_mon--;
 
     // Print 12 months of the year
old mode 100644 (file)
new mode 100755 (executable)
index 4292439..64369b6
@@ -39,7 +39,7 @@ GLOBALS(
   char *mode;
 )
 
-static int do_chmod(struct dirtree *try)
+int do_chmod(struct dirtree *try)
 {
   mode_t mode;
 
old mode 100644 (file)
new mode 100755 (executable)
index 829da75..2dae113
@@ -28,7 +28,7 @@ GLOBALS(
 
 // This handles opening the file and
 
-static void do_cmp(int fd, char *name)
+void do_cmp(int fd, char *name)
 {
   int i, len1, len2, min_len, size = sizeof(toybuf)/2;
   long byte_no = 1, line_no = 1;
index 6a395a4..d5e92f2 100644 (file)
@@ -7,9 +7,9 @@
 // options shared between mv/cp must be in same order (right to left)
 // for FLAG macros to work out right in shared infrastructure.
 
-USE_CP(NEWTOY(cp, "<2"USE_CP_PRESERVE("(preserve):;")"RHLPp"USE_CP_MORE("rdasl"USE_CP_Z("Z")"vnF(remove-destination)")"fi[-HLP"USE_CP_MORE("d")"]"USE_CP_MORE("[-ni]"), TOYFLAG_BIN))
-USE_MV(NEWTOY(mv, "<2"USE_CP_Z("Z")""USE_CP_MORE("vnF")"fi"USE_CP_MORE("[-ni]"), TOYFLAG_BIN))
-USE_INSTALL(NEWTOY(install, "<1"USE_INSTALL_Z("Z:")"cdDpsvm:o:g:", TOYFLAG_USR|TOYFLAG_BIN))
+USE_CP(NEWTOY(cp, "<2"USE_CP_PRESERVE("(preserve):;")"RHLPp"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))
 
 config CP
   bool "cp"
@@ -49,7 +49,7 @@ config CP_PRESERVE
   default y
   depends on CP_MORE
   help
-    usage: cp [--preserve=motca]
+    usage: cp [--preserve=mota]
 
     --preserve takes either a comma separated list of attributes, or the first
     letter(s) of:
@@ -57,18 +57,8 @@ config CP_PRESERVE
             mode - permissions (ignore umask for rwx, copy suid and sticky bit)
        ownership - user and group
       timestamps - file creation, modification, and access times.
-         context - preserve src's context.
              all - all of the above
 
-config CP_Z
-  bool
-  default y
-  depends on CP_MORE && !TOYBOX_LSM_NONE
-  help
-    usage: cp [-Z]
-
-    set security context of destination file to default type
-
 config MV
   bool "mv"
   default y
@@ -106,15 +96,6 @@ config INSTALL
     -p Preserve timestamps
     -s Call "strip -p"
     -v Verbose
-
-config INSTALL_Z
-  bool
-  default y
-  depends on INSTALL && !TOYBOX_LSM_NONE
-  help
-    usage: [-Z context]
-
-    -Z  set security context
 */
 
 #define FOR_cp
@@ -127,11 +108,9 @@ GLOBALS(
       char *group;
       char *user;
       char *mode;
-      char *context;
     } i;
     struct {
       char *preserve;
-      char *context;
     } c;
   };
 
@@ -337,14 +316,9 @@ int cp_node(struct dirtree *try)
       xclose(fdout);
     }
 
-    if (CFG_MV && toys.which->name[0] == 'm') {
+    if (CFG_MV && toys.which->name[0] == 'm')
       if (unlinkat(tfd, try->name, S_ISDIR(try->st.st_mode) ? AT_REMOVEDIR :0))
         err = "%s";
-      if (CFG_CP_Z) {
-        if (0>lsm_lset_context(catch, TT.c.context))
-          perror_exit("-Z '%s' failed", TT.c.context);
-      }
-    }
   }
 
   if (err) perror_msg(err, catch);
@@ -354,7 +328,7 @@ int cp_node(struct dirtree *try)
 void cp_main(void)
 {
   char *destname = toys.optargs[--toys.optc],
-       *preserve[] = {"mode", "ownership", "timestamps", "context"};
+       *preserve[] = {"mode", "ownership", "timestamps"};
   int i, destdir = !stat(destname, &TT.top) && S_ISDIR(TT.top.st_mode);
 
   if (toys.optc>1 && !destdir) error_exit("'%s' not directory", destname);
@@ -396,30 +370,8 @@ void cp_main(void)
     if (destdir) TT.destname = xmprintf("%s/%s", destname, basename(src));
     else TT.destname = destname;
 
-    // Preserve Context
-    if (TT.pflags & 8) {
-      TT.c.context = NULL;
-      if (!CFG_TOYBOX_LSM_NONE && lsm_enabled()) {
-        if (0>lsm_lget_context(src, &TT.c.context))
-          perror_exit("unknown security context for '%s'", src);
-        if (0>lsm_set_create(TT.c.context))
-          perror_exit("preserve context '%s' failed", TT.c.context);
-        free(TT.c.context);
-      } else error_exit("%s disabled", lsm_name());
-    }
-
     errno = EXDEV;
     if (CFG_MV && toys.which->name[0] == 'm') {
-      if (CFG_CP_Z) {
-        if (lsm_enabled()) {
-          TT.c.context = NULL;
-          if (toys.optflags & FLAG_Z) TT.c.context = lsm_context();
-          else {
-            if (0>lsm_lget_context(src, &TT.c.context))
-              perror_exit("unknown security context for '%s'", src);
-          }
-        } else error_exit("%s disabled", lsm_name());
-      }
       if (!(toys.optflags & FLAG_f)) {
         struct stat st;
 
@@ -434,14 +386,7 @@ void cp_main(void)
         }
       }
 
-      if (rc) {
-        rc = rename(src, TT.destname);
-        if (CFG_CP_Z) {
-          if (!rc && (toys.optflags&FLAG_Z)
-              && (0>lsm_lset_context(TT.destname, TT.c.context)))
-            perror_exit("-Z '%s' failed", TT.c.context);
-        }
-      }
+      if (rc) rc = rename(src, TT.destname);
     }
 
     // Skip nonexistent sources
@@ -452,9 +397,6 @@ void cp_main(void)
       else dirtree_handle_callback(new, TT.callback);
     }
     if (destdir) free(TT.destname);
-    if (CFG_CP_Z && CFG_MV && toys.which->name[0] == 'm'
-        && (toys.optflags & FLAG_Z))
-      free(TT.c.context);
   }
 }
 
@@ -490,13 +432,6 @@ void install_main(void)
   char **ss;
   int flags = toys.optflags;
 
-  if (CFG_INSTALL_Z && (toys.optflags&FLAG_Z)) {
-    if (lsm_enabled()) {
-      if (0>lsm_set_create(TT.i.context))
-        perror_exit("bad -Z '%s'", TT.i.context);
-    } else error_msg("%s disabled", lsm_name());
-  }
-
   if (flags & FLAG_d) {
     for (ss = toys.optargs; *ss; ss++) {
       if (mkpathat(AT_FDCWD, *ss, 0777, 3)) perror_msg("%s", *ss);
old mode 100644 (file)
new mode 100755 (executable)
index a42de50..d4c4524
@@ -7,23 +7,22 @@
  * Note: setting a 2 year date is 50 years back/forward from today,
  * not posix's hardwired magic dates.
 
-USE_DATE(NEWTOY(date, "d:D:r:u[!dr]", TOYFLAG_BIN))
+USE_DATE(NEWTOY(date, "d:s:r:u[!dr]", TOYFLAG_BIN))
 
 config DATE
   bool "date"
   default y
   help
-    usage: date [-u] [-r FILE] [-d DATE] [+DISPLAY_FORMAT] [-D SET_FORMAT] [SET]
+    usage: date [-u] [-r FILE] [-d DATE] [+DISPLAY_FORMAT] [-s SET_FORMAT] [SET]
 
     Set/get the current date/time. With no SET shows the current date.
 
     Default SET format is "MMDDhhmm[[CC]YY][.ss]", that's (2 digits each)
     month, day, hour (0-23), and minute. Optionally century, year, and second.
-    Also accepts "@UNIXTIME[.FRACTION]" as seconds since midnight Jan 1 1970.
 
     -d Show DATE instead of current time (convert date format)
-    -D +FORMAT for SET or -d (instead of MMDDhhmm[[CC]YY][.ss])
     -r Use modification time of FILE instead of current date
+    -s +FORMAT for SET or -d (instead of MMDDhhmm[[CC]YY][.ss])
     -u Use UTC instead of current timezone
 
     +FORMAT specifies display format string using these escapes:
@@ -50,79 +49,15 @@ GLOBALS(
   char *file;
   char *setfmt;
   char *showdate;
-
-  char *tz;
-  unsigned nano;
 )
 
-// mktime(3) normalizes the struct tm fields, but date(1) shouldn't.
-static time_t chkmktime(struct tm *tm, const char *str, const char* fmt)
-{
-  struct tm tm0 = *tm;
-  struct tm tm1;
-  time_t t = mktime(tm);
-
-  if (t == -1 || !localtime_r(&t, &tm1) ||
-      tm0.tm_sec != tm1.tm_sec || tm0.tm_min != tm1.tm_min ||
-      tm0.tm_hour != tm1.tm_hour || tm0.tm_mday != tm1.tm_mday ||
-      tm0.tm_mon != tm1.tm_mon) {
-    int len;
-
-    strftime(toybuf, sizeof(toybuf), fmt, &tm0);
-    len = strlen(toybuf) + 1;
-    strftime(toybuf + len, sizeof(toybuf) - len, fmt, &tm1);
-    error_exit("bad date '%s'; %s != %s", str, toybuf, toybuf + len);
-  }
-  return t;
-}
-
-static void utzset(void)
-{
-  if (!(TT.tz = getenv("TZ"))) TT.tz = (char *)1;
-  setenv("TZ", "UTC", 1);
-  tzset();
-}
-
-static void utzreset(void)
-{
-  if (TT.tz) {
-    if (TT.tz != (char *)1) setenv("TZ", TT.tz, 1);
-    else unsetenv("TZ");
-    tzset();
-  }
-}
-
-// Handle default posix date format (mmddhhmm[[cc]yy]) or @UNIX[.FRAC]
+// Handle default posix date format: mmddhhmm[[cc]yy]
 // returns 0 success, nonzero for error
-static int parse_default(char *str, struct tm *tm)
+int parse_posixdate(char *str, struct tm *tm)
 {
-  int len = 0;
-
-  // Parse @UNIXTIME[.FRACTION]
-  if (*str == '@') {
-    long long ll;
-    time_t tt;
-
-    // Collect seconds and nanoseconds
-    // Note: struct tm hasn't got a fractional seconds field, thus strptime()
-    // doesn't support it, so store nanoseconds out of band (in globals).
-    // tt and ll are separate because we can't guarantee time_t is 64 bit (yet).
-    sscanf(str, "@%lld%n", &ll, &len);
-    if (str[len]=='.') {
-      str += len+1;
-      for (len = 0; len<9; len++) {
-        TT.nano *= 10;
-        if (isdigit(str[len])) TT.nano += str[len]-'0';
-      }
-    }
-    if (str[len]) return 1;
-    tt = ll;
-    gmtime_r(&tt, tm);
-
-    return 0;
-  }
+  int len;
 
-  // Posix format
+  len = 0;
   sscanf(str, "%2u%2u%2u%2u%n", &tm->tm_mon, &tm->tm_mday, &tm->tm_hour,
     &tm->tm_min, &len);
   if (len != 8) return 1;
@@ -143,38 +78,40 @@ static int parse_default(char *str, struct tm *tm)
     // 2 digit years, next 50 years are "future", last 50 years are "past".
     // A "future" date in past is a century ahead.
     // A non-future date in the future is a century behind.
-    if (len == 2) {
-      if ((r1 < r2) ? (r1 < year && year < r2) : (year < r1 || year > r2)) {
-        if (year < r1) year += 100;
-      } else if (year > r1) year -= 100;
-    }
+    if ((r1 < r2) ? (r1 < year && year < r2) : (year < r1 || year > r2)) {
+      if (year < r1) year += 100;
+    } else if (year > r1) year -= 100;
     tm->tm_year = year + century;
   }
   if (*str == '.') {
     len = 0;
     sscanf(str, ".%u%n", &tm->tm_sec, &len);
     str += len;
-  } else tm->tm_sec = 0;
+  }
 
   return *str;
 }
 
 void date_main(void)
 {
-  char *setdate = *toys.optargs, *format_string = "%a %b %e %H:%M:%S %Z %Y";
+  char *setdate = *toys.optargs, *format_string = "%a %b %e %H:%M:%S %Z %Y",
+       *tz = 0;
   struct tm tm;
 
-  memset(&tm, 0, sizeof(struct tm));
-
   // We can't just pass a timezone to mktime because posix.
-  if (toys.optflags & FLAG_u) utzset();
+  if (toys.optflags & FLAG_u) {
+    if (CFG_TOYBOX_FREE) tz = getenv("TZ");
+    setenv("TZ", "UTC", 1);
+    tzset();
+  }
 
   if (TT.showdate) {
+    setdate = TT.showdate;
     if (TT.setfmt) {
       char *s = strptime(TT.showdate, TT.setfmt+(*TT.setfmt=='+'), &tm);
 
-      if (!s || *s) goto bad_showdate;
-    } else if (parse_default(TT.showdate, &tm)) goto bad_showdate;
+      if (!s || *s) goto bad_date;
+    } else if (parse_posixdate(TT.showdate, &tm)) goto bad_date;
   } else {
     time_t now;
 
@@ -188,6 +125,7 @@ void date_main(void)
     ((toys.optflags & FLAG_u) ? gmtime_r : localtime_r)(&now, &tm);
   }
 
+  setdate = *toys.optargs;
   // Fall through if no arguments
   if (!setdate);
   // Display the date?
@@ -199,26 +137,39 @@ void date_main(void)
   } else if (setdate) {
     struct timeval tv;
 
-    if (parse_default(setdate, &tm)) error_exit("bad date '%s'", setdate);
+    if (parse_posixdate(setdate, &tm)) goto bad_date;
 
     if (toys.optflags & FLAG_u) {
+      char *tz = CFG_TOYBOX_FREE ? getenv("TZ") : 0;
+
       // We can't just pass a timezone to mktime because posix.
-      utzset();
-      tv.tv_sec = chkmktime(&tm, setdate, format_string);
-      utzreset();
-    } else tv.tv_sec = chkmktime(&tm, setdate, format_string);
+      setenv("TZ", "UTC", 1);
+      tzset();
+      tv.tv_sec = mktime(&tm);
+      if (CFG_TOYBOX_FREE) {
+        if (tz) setenv("TZ", tz, 1);
+        else unsetenv("TZ");
+        tzset();
+      }
+    } else tv.tv_sec = mktime(&tm);
+    if (tv.tv_sec == (time_t)-1) goto bad_date;
 
-    tv.tv_usec = TT.nano/1000;
+    tv.tv_usec = 0;
     if (settimeofday(&tv, NULL) < 0) perror_msg("cannot set date");
   }
 
-  utzreset();
+  if (toys.optflags & FLAG_u) {
+    if (tz) setenv("TZ", tz, 1);
+    else unsetenv("TZ");
+    tzset();
+  }
+
   if (!strftime(toybuf, sizeof(toybuf), format_string, &tm))
     perror_exit("bad format '%s'", format_string);
   puts(toybuf);
 
   return;
 
-bad_showdate:
-  error_exit("bad date '%s'", TT.showdate);
+bad_date:
+  error_exit("bad date '%s'", setdate);
 }
old mode 100644 (file)
new mode 100755 (executable)
index 77c7b6e..4302997
@@ -57,7 +57,7 @@ static void print(long long size, struct dirtree *node)
   if (TT.maxdepth && TT.depth > TT.maxdepth) return;
 
   if (toys.optflags & FLAG_h) {
-    human_readable(toybuf, size, 0);
+    human_readable(toybuf, size);
     printf("%s", toybuf);
   } else {
     int bits = 10;
old mode 100644 (file)
new mode 100755 (executable)
index 99cf5e2..a11a910
@@ -141,6 +141,41 @@ static void do_print(struct dirtree *new, char c)
   free(s);
 }
 
+char *strlower(char *s)
+{
+  char *try, *new;
+
+  if (!CFG_TOYBOX_I18N) {
+    try = new = xstrdup(s);
+    for (; *s; s++) *(new++) = tolower(*s);
+  } else {
+    // I can't guarantee the string _won't_ expand during reencoding, so...?
+    try = new = xmalloc(strlen(s)*2+1);
+
+    while (*s) {
+      wchar_t c;
+      int len = mbrtowc(&c, s, MB_CUR_MAX, 0);
+
+      if (len < 1) *(new++) = *(s++);
+      else {
+        s += len;
+        // squash title case too
+        c = towlower(c);
+
+        // if we had a valid utf8 sequence, convert it to lower case, and can't
+        // encode back to utf8, something is wrong with your libc. But just
+        // in case somebody finds an exploit...
+        len = wcrtomb(new, c, 0);
+        if (len < 1) error_exit("bad utf8 %x", (int)c);
+        new += len;
+      }
+    }
+    *new = 0;
+  }
+
+  return try;
+}
+
 // Call this with 0 for first pass argument parsing and syntax checking (which
 // populates argdata). Later commands traverse argdata (in order) when they
 // need "do once" results.
old mode 100644 (file)
new mode 100755 (executable)
index 01610bc..aa43072
@@ -82,7 +82,7 @@ static void showid(char *header, unsigned u, char *s)
   printf("%s%u(%s)", header, u, s);
 }
 
-static void do_id(char *username)
+void do_id(char *username)
 {
   int flags, i, ngroups;
   struct passwd *pw;
old mode 100644 (file)
new mode 100755 (executable)
index f951198..44915fa
@@ -422,13 +422,6 @@ static void listfiles(int dirfd, struct dirtree *indir)
       mode_to_string(mode, perm);
       printf("%s% *ld", perm, totals[2]+1, (long)st->st_nlink);
 
-      // print user
-      if (!(flags&FLAG_g)) {
-        if (flags&FLAG_n) sprintf(ss = thyme, "%u", (unsigned)st->st_uid);
-        else strwidth(ss = getusername(st->st_uid));
-        printf(" %*s", (int)totals[3], ss);
-      }
-
       // print group
       if (!(flags&FLAG_o)) {
         if (flags&FLAG_n) sprintf(ss = thyme, "%u", (unsigned)st->st_gid);
@@ -436,6 +429,12 @@ static void listfiles(int dirfd, struct dirtree *indir)
         printf(" %*s", (int)totals[4], ss);
       }
 
+      if (!(flags&FLAG_g)) {
+        if (flags&FLAG_n) sprintf(ss = thyme, "%u", (unsigned)st->st_uid);
+        else strwidth(ss = getusername(st->st_uid));
+        printf(" %*s", (int)totals[3], ss);
+      }
+
       if (flags & FLAG_Z)
         printf(" %*s", -(int)totals[7], (char *)sort[next]->extra);
 
old mode 100644 (file)
new mode 100755 (executable)
index 60c0a52..c7e7b92
@@ -40,7 +40,7 @@ GLOBALS(
   long lcount;
 )
 
-static void do_nl(int fd, char *name)
+void do_nl(int fd, char *name)
 {
   FILE *f = xfdopen(fd, "r");
   int w = TT.w, slen = strlen(TT.s);
old mode 100644 (file)
new mode 100755 (executable)
index 075a414..aabf931
@@ -35,7 +35,7 @@ GLOBALS(
   char *outfile;
 )
 
-static void do_split(int infd, char *in)
+void do_split(int infd, char *in)
 {
   unsigned long bytesleft, linesleft, filenum, len, pos;
   int outfd = -1;
old mode 100644 (file)
new mode 100755 (executable)
index e87ccde..a872cf6
@@ -29,7 +29,7 @@ GLOBALS(
   long num;
 )
 
-static void do_strings(int fd, char *filename)
+void do_strings(int fd, char *filename)
 {
   int nread, i, wlen = TT.num, count = 0;
   off_t offset = 0;
diff --git a/toys/samsung/README b/toys/samsung/README
deleted file mode 100644 (file)
index fa82bef..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Samsung developed commands
-
-These are commands developed at Samsung Electrnocis Co. Ltd.
diff --git a/toys/samsung/nslookup.c b/toys/samsung/nslookup.c
deleted file mode 100644 (file)
index ac8f8ec..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/* nslookup.c - query Internet name servers
- *
- * Copyright 2013 Ashwini Kumar <ak.ashwini@gmail.com>
- * Copyright 2015 Rajni Kant <rajnikant12345@gmail.com>
- *
-
-USE_NSLOOKUP(NEWTOY(nslookup, "<1?", TOYFLAG_USR|TOYFLAG_BIN))
-
-config NSLOOKUP
-  bool "nslookup"
-  default y
-  help
-    usage: nslookup [HOST] [SERVER]
-
-    Query the nameserver for the IP address of the given HOST
-    optionally using a specified DNS server.
-
-    Note:- Only non-interactive mode is supported.
-*/
-
-#define FOR_nslookup
-#include "toys.h"
-#include <resolv.h>
-
-static char *address_to_name(struct sockaddr *sock)
-{
-  //man page of getnameinfo.
-  char hbuf[NI_MAXHOST] = {0,}, sbuf[NI_MAXSERV] = {0,};
-  int status = 0;
-  if (sock->sa_family == AF_INET) {
-    socklen_t len = sizeof(struct sockaddr_in);
-    if ((status = getnameinfo(sock, len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
-            NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
-      return xmprintf("%s:%s", hbuf, sbuf);
-    else {
-      fprintf(stderr, "getnameinfo: %s\n", gai_strerror(status));
-      return NULL;
-    }
-  }
-  else if (sock->sa_family == AF_INET6) {
-    socklen_t len = sizeof(struct sockaddr_in6);
-    if ((status = getnameinfo(sock, len, hbuf, sizeof(hbuf), sbuf, 
-            sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0) {
-      //verification for resolved hostname.
-      if (strchr(hbuf, ':')) return xmprintf("[%s]:%s", hbuf, sbuf);
-      else return xmprintf("%s:%s", hbuf, sbuf);
-    }
-    else {
-      fprintf(stderr, "getnameinfo: %s\n", gai_strerror(status));
-      return NULL;
-    }
-  }
-  else if (sock->sa_family == AF_UNIX) {
-    struct sockaddr_un *sockun = (void*)sock;
-    return xmprintf("local:%.*s", (int) sizeof(sockun->sun_path), sockun->sun_path);
-  }
-  return NULL;
-}
-
-static void print_addrs(char *hostname, char *msg)
-{
-  struct addrinfo hints, *res = NULL, *cur = NULL;
-  int ret_ga;
-  char *n = xstrdup(hostname), *p, *tmp;
-  tmp = n;
-  if ((*n == '[') && (p = strrchr(n, ']')) != NULL ) {
-    n++;
-    *p = '\0';
-  }
-
-  memset(&hints, 0, sizeof(struct addrinfo));
-  hints.ai_socktype = SOCK_STREAM;
-
-  ret_ga = getaddrinfo(n, NULL, &hints, &res);                                                                                                       
-  if (ret_ga) perror_exit("Hostname %s", gai_strerror(ret_ga));
-
-  cur = res;
-  while(cur) {
-    char *colon = NULL;
-    char *name = address_to_name(cur->ai_addr);
-    if (name) {
-      colon = strrchr(name, ':');
-      if (colon) *colon = '\0';
-      xprintf("%-8s %s\n",msg, hostname);
-      xprintf("Address: %s\n", name);
-      free(name);
-    }
-    cur = cur->ai_next;
-  }
-  if (!res->ai_addr) error_exit("getaddrinfo failed");
-
-  freeaddrinfo(res);
-  free(tmp);
-}
-
-static void resolve_addr(char *host, void *addr, char* port)
-{
-  struct addrinfo *info, hint;
-  int ret = atolx(port);
-  
-  if(ret <0 || ret > 65535 ) error_exit("bad port:  %s", port);
-  if (strncmp(host, "local:", 6) == 0) {  
-    struct sockaddr *sockun = (struct sockaddr *)addr;   
-    sockun->sa_family = AF_UNIX;
-    strncpy(((struct sockaddr_un *)sockun)->sun_path, host + 6, 
-            sizeof(((struct sockaddr_un *)sockun)->sun_path));
-    return ;   
-  }   
-  memset(&hint, 0, sizeof(hint));
-
-  ret = getaddrinfo(host, port , &hint, &info);
-  
-  if (ret || !info) error_exit("bad address:  %s", host);
-
-  memcpy(addr, info->ai_addr, info->ai_addrlen);
-  freeaddrinfo(info);
-}
-
-void nslookup_main(void)
-{
-  struct sockaddr* sock;
-  char *args[2] = {0,0}, *colon = NULL, *name = NULL;
-  
-  res_init(); //initialize the _res struct, for DNS name.
-
-  for (;*toys.optargs; toys.optargs++) {
-    if (**toys.optargs == '-') {
-      if (!strncmp(&toys.optargs[0][1], "retry=", 6)) {
-        _res.retry = atolx(toys.optargs[0]+7);
-      } else if (!strncmp(&toys.optargs[0][1], "timeout=", 8)) {
-        _res.retrans = atolx(toys.optargs[0]+9);
-      } else error_msg("invalid option '%s'", *toys.optargs);
-    } else if (!args[0]) args[0] = *toys.optargs;
-    else if (!args[1]) args[1] = *toys.optargs;
-    else error_exit("bad arg '%s'",*toys.optargs);
-  }
-
-  if ( !*args) {
-    toys.exithelp++;
-    error_exit("Needs 1 args minimum");
-  }
-  if (args[1]) { //set the default DNS
-    struct sockaddr_storage addr;
-    char* port = NULL ;
-    
-    if (args[1][0] == '[') {
-      int len = strchr(args[1],']') - &args[1][0];
-      if (len > 45|| len <= 0 ) error_exit("bad address:  %s", args[1]);
-      strncpy(toybuf,&args[1][1], len-1);
-      args[1] += len;
-    }
-    if ((port = strchr(args[1],':'))) {
-      *port = '\0';
-      port++;
-    }
-    else port = "53";
-    resolve_addr((toybuf[0])?toybuf:args[1], &addr, port );
-
-    if (addr.ss_family == AF_INET) {
-      _res.nscount = 1;
-      _res.nsaddr_list[0] = *((struct sockaddr_in*)&addr);
-    }
-    else if (addr.ss_family == AF_INET6) {
-      _res._u._ext.nscount = 1;
-      _res._u._ext.nsaddrs[0] = ((struct sockaddr_in6*)&addr);
-    }
-  }
-
-  sock = (struct sockaddr*)_res._u._ext.nsaddrs[0];
-  if (!sock) sock = (struct sockaddr*)&_res.nsaddr_list[0];
-  if ((name = address_to_name(sock))) {
-    colon = strrchr(name, ':');
-    if (colon) *colon = '\0';
-    print_addrs(name, "Server:");
-    free(name);
-  }
-  puts("");
-
-  print_addrs(args[0], "Name:");  
-}
index 0c5da77..084d753 100755 (executable)
@@ -8,245 +8,7 @@ a development environment. See the links on the left for details.</p>
 
 <h2>News</h2>
 
-<a name="23-07-2015" /><a href="#23-07-2015"><hr><h2><b>July 23, 2015</b></h2></a>
-<p>I recreated the <a href=downloads/toybox-0.6.0.tar.gz>0.6.0 source tarball</a>
-(new sha1sum 08fb1c23f520c25a15f262a8a95ea5b676a98d54)
-because I forgot to add --prefix to the git archive command when I updated
-my release script from mercurial, so the files weren't in an enclosing
-directory. (Ooops.)</p>
-
-<a name="19-07-2015" /><a href="#19-07-2015"><hr><h2><b>July 19, 2015</b></h2></a>
-<blockquote><p>
-The reason why it was published in the form of a micro sub meson electronic
-component is that if it were printed in normal book form, an interstellar
-hitchhiker would require several inconveniently large buildings to carry it
-around in." - The Hitchhiker's Guide to the Galaxy </p></blockquote>
-
-<p><a href=downloads/toybox-0.6.0.tar.gz>Toybox 0.6.0</a>
-(<a href=https://github.com/landley/toybox/releases/tag/0.6.0>git commit</a>)
-is out. (Yes, git. See the <a href=#05-04-2015>previous news entry</a>.)</p>
-
-<p>Sorry for the unusually long gap between releases. Since last release Ye
-Olde Project Maintainer traveled to japan twice and had two more "once
-a century" floods at home. (Probably a coincidence.) Still catching up.</p>
-
-<h3><b>CELF/ELC talk and Wikipedia[citation needed] article</b></h3>
-
-<p>I gave another State Of The Toybox talk
-(<a href=https://www.youtube.com/watch?v=04XwAbtPmAg>video</a>
-<a href=http://landley.net/talks/celf-2015.txt>outline</a>), in which I
-repeat my <a href=http://landley.net/notes-2013.html#07-11-2013>perennial</a>
-<a href=https://twitter.com/landley/status/557309224535851009>complaint</a>
-that Wikipedia[citation needed]
-<a href=http://en.wikipedia.org/wiki/Toybox>still</a>
-<a href=https://en.wikipedia.org/wiki/BusyBox#Controversy_over_Toybox>says</a>
-toybox was relicensed before its hiatus, when relicensing was why
-the hiatus ended.</p>
-
-<p>Since Wikipedia[citation needed] seems unable to do the
-<a href=#15-11-2011>most</a>
-<a href=http://landley.net/hg/toybox/log/tip/LICENSE>basic</a>
-<a href=http://landley.net/notes-2011.html#13-11-2011>research</a> on
-this point, and has stuck to an incorrect sequence of events for years,
-I've been gradually escalating my attempts to correct them. Toybox
-came out of mothballs in November 2011 <b>because</b> it could be
-relicensed. That's what opened up a new niche busybox wasn't already
-filling with a 10 year headstart.</p>
-
-<a name="asterisk_back" />
-<p>The article has plenty of smaller issues<a href=#asterisk>*</a>, but
-given that I gave an entire talk at Ohio LinuxFest in 2013
-(<a href=http://landley.net/talks/ohio-2013.txt>outline</a>,
-<a href=https://archive.org/download/OhioLinuxfest2013/24-Rob_Landley-The_Rise_and_Fall_of_Copyleft.mp3>audio</a>) on why I switched away from GPL for
-my projects, that one bugs me.</p>
-
-<h3><b>New stuff this release</b></h3>
-
-<p>There's a new android menu in menuconfig, and rather a lot of Linux
-Security Module support (Smack for Tizen from Xavier Roche and José Bollo,
-and SELinux for Android from Elliott Hughes; see
-the Security Blanket menu under global settings in menuconfig) has
-trickled in, although there's still more to come.</p>
-
-<p><b>New commands:</b> Added reset, nproc, ionice, and iorenice.
-Elliott Hughes contributed xxd, runcon,
-restorecon, load_policy, getenforce, setenforce, getprop, and setprop.
-Promoted shred, nsenter, and hwclock.</p>
-
-<p>You can once again build catv now the flag infrastructure's been updated to
-let it coexist with cat -v.
-And on a long plane flight I wrote
-hexedit, an interactive hex editor that implements the start of
-cursor control infrastructure (for eventual use by less and vi and shell
-command history and so on).</p>
-
-<p><b>New options:</b> Added sed -E as a BSD-compatible synonym for -r.
-Upgraded oneit with -r (restart), -3 (send exiting PID values to child),
-and signal handling. Added -v option to timeout, -m to mknod, -u to shred,
--t to dmesg, and -123 to head and tail. Added implicit "." to grep -r without
-any files to work on. Hyejin Kim requested prefix support for truncate -s.
-Greg Hackman added -inum to find.
-Jan Cybulski added the smack side of ls -Z support. Various patches also
-added -Z to mkdir, mknod, and mkfifo.
-Basic cp --preserve support went in, but not yet the xattr/LSM parts.</p>
-
-<p>The toybox command now has a --version option,
-which uses "git describe" if available.</p>
-
-<p><b>Build infrastructure:</b>
-The "make change" target now saves the output of each failed standalone
-command build in a .bad file, and "make defconfig" is quieter now.</p>
-
-<p>Paul Barker submitted a large patch changing command install paths so
-"toybox can be installed alongside busybox without confusing
-update-alternatives". (There's some argument over
-what the right paths should be, and I'm waiting for
-people to tell me what else needs fixing because I have no idea. I've
-been symlinking /bin to /usr/bin since 2002
-<a href=http://landley.net/writing/hackermonthly-issue022-pg33.pdf>for
-historical reasons</a>.)</p>
-
-<p><b>Docs:</b> The repository link now goes to github, with another link
-to the commit rss feed.</p>
-
-<p>Elliott Hughes updated the Android section of the roadmap
-(and he would know). Redid bits of scripts/mkstatus.py to make updating
-status.html easier, and the README is larger.</p>
-
-<p>More description of option parsing in code.html, which now describes the
-FLAG_x macros, switching flag macro sets with FOR_newcommand, how
-configuration zeroes flag macros and using FORCE_FLAGS to suppress the
-zeroing of options shared between commands. Also added description of ";"
-to make --longopts take an optional =value part, and more about TOYBOX_DEBUG
-to check NEWTOY() option strings (otherwise a bad option string makes
-lib/args.c obviously segfault, but doesn't explain why).</p>
-
-<p>Added a "Why 0BSD?" section to license.html when submitting zero clause bsd
-to SPDX (according to the pending license spreadsheet, it's been approved for
-SPDX 2.2).</p>
-
-<p>The old list of commands needing cleanup but not in pending was
-removed from toys/pending/README and instead the issues were added
-as TODO comments in the individual commands.</p>
-
-<p><b>Bugfixes:</b>
-Fixed mount -a segfaulting without -O (reported by Janus Troelsen),
-and made it try a "become rw" ioctl() on the block device before falling
-back to mounting read only (because Android expects that).
-Fixed printf -- and printf ---. Lots of tweaks to ls -l spacing with
-different options. Make touch -d and -t actually set time when you don't
-specify nanoseconds.
-Fixed a subtle bug where recursive calls (toybox commands that run other
-toybox commands) weren't resetting all their state. (This manifested as
-a "no }" error from "find | xargs sed", but could cause other problems.)
-And David Halls reported another sed bug trying to compile libiconv (which
-left extra \ at the start of lines in a generated shell script, breaking
-the build). Output an error message for "cat /mnt".</p>
-
-<p>Kylie McClain reported that mktemp broke when $TMPDIR was set to an empty
-string (which is not the same as unset), that install/find didn't support
-numeric uid/gids, and that sort -z affects both input and output.
-Isabella Parakiss fixed a printf.c bug.
-David Halls fixed bugs in install -D and find -exec. Samuel Holland
-fixed unshare -r. Hyejin Kim fixed makedevs with a count of 1, fold -w
-range checking, an error path in scripts/mkflags.c, added -i to dhcpd,
-and stopped su from prompting the root user for the new user's password.
-Jan Cybulski spotted wrong indentation when combining ls -s and -i with -C and
--x. José Bollo fixed stat %G. Sameer Pradhan fixed a bug in mkfifo -Z.</p>
-
-<p>Elliott Hughes asked for a default SIGPIPE handler to disable
-the signal handler bionic's dynamic loader installs (yes really). Still not
-100% sure what the correct behavior is there. (Posix is
-(<a href=http://permalink.gmane.org/gmane.comp.standards.posix.austin.general/10915>actively unhelpful</a>, but at least they're taking
-<a href=http://austingroupbugs.net/view.php?id=789#c1976>years to
-make up their mind</a>. Elliott also sent patches to fix a typo in
-useradd.test, add missing arguments to error_exit() calls and clean up
-printf() format strings, fix an off by one error in human_readable(),
-fix dmesg -c error reporting, fix a segfault in comma_scan where the option
-was the last item in optlist (triggered by mount -o ro,remount), fix
-hwclock -w, made ifconfig print lowercase MAC addresses (it was bothering
-him), and make terminal_size() read the right environment variable
-(LINES, not ROWS). And he suggested the test suite notice high command exit
-values (corresponding to segfault or other signals).</p>
-
-<p>People are apparently using toys/pending commands, despite the police tape
-and flashing lights, so added louder warnings to toys/pending/README.
-Elliott Hughes fixed various problems with tar, dd, more, and top.
-Hyejin Kim cleaned up syslogd and dumpleases. Isaac Dunham added hotplug
-support to mdev. Yeongdeok Suh added RFC-3315 ipv6 support to dhcpd.</p>
-
-<p>I rewrote ps.c from scratch (in pending), but it's not ready for real use
-yet.</p>
-
-<p><b>Portability:</b>
-On the portability front Bernhard Rosenkranzer fixed a problem where the
-menuconfig code wouldn't compile in C99 mode. (This led to me documenting
-the craptacular nature of kconfig in a README, and the plan to replace it
-sometime before 1.0.) Some extra flags to shut up overzealous llvm warnings
-were added (and have to be probed for because gcc complains about
-arguments it doesn't recognize even when they switch stuff _off_ using
-a standard syntax). Don't depend on malloc(0) to return non-null in ls.
-David Halls fixed some mac/ios portability issues,
-implying somebody's built at least part of toybox on a mac.</p>
-
-<p>Added basename_r() to lib/lib.c because the posix semantics for basename()
-are stupid but what the gnu guys did to it was appalling.
-Turns out bionic already had a basename_r(), but posix still doesn't.
-Fixed it up in portability.h, but this
-could break more stuff in future. (Correct fix is to lobby posix to add it,
-which would probably take about 15 years...)</p>
-
-<p><b>Infrastructure:</b>
-The build now checks $LDFLAGS for linker-only flags, and allows the strip
-command to fail (binflt toolchains provide a strip that doesn't work).
-Since time.c uses floating point, added TOYBOX_FLOAT dependency in config.</p>
-
-<p>There's a lib/lsm.h defining varous inline functions for linux
-security modules stuff, if (lsm_enabled()) should turn into a compile-time
-constant 0 and let code drop out when TOYBOX_LSM_NONE selected, but
-testing against CFG_TOYBOX_LSM_NONE or derived symbols is still useful
-becuase when it _is_ enabled the probe turns into a system call you
-don't want to repeat too much.</p>
-
-<p>Switched a bunch of commands from signal() to xsignal(). Factored out
-xgetgrnamid() and xgetpwnamid() into xwrap.c. Make time.c depend on
-TOYBOX_FLOAT (since it always uses float so shouldn't be available on
-build targets without even software float). Added readfileat() to lib/lib.c.</p>
-
-<p>The dirtree infrastructure now passes in full flags for the old symlink
-field, and the new DIRTREE_SHUTUP flag disables warnings if a file vanishes
-out from under you during traverse. New dirtree_start() wrapper to
-create dirtree root with only two arguments.</p>
-
-<p>The not-curses infrastructure introduced by hexedit mostly moved to
-lib/interestingtimes.c.</p>
-
-<a name="asterisk" />
-<a href="#asterisk_back" />Asterisk:</a> such when
-Tim contacted me (my blog says a couple days before nov 13, 2011, I.E.
-11/11/11 not some specific day 2 months later) to ask if I wanted to work
-on a new project he was proposing called
-<a href=http://www.elinux.org/Busybox_replacement_project>BentoBox</a>
-(because I used to do busybox, he'd forgotten toybox existed
-until I brought it up). And don't ask me what "focuses not on compatibility
-with its GNU counterparts" means when CP_MORE adds 7 non-posix options
-and toys/other has 84 commands in neither posix nor LSB. I think they're
-struggling to explain the difference having dismissed "licensing" as being
-the reason it started up again after a long hiatus? The reason I don't think
-GNU is special is there are a half-dozen other independent
-implementations of the same unix command tools out there (AT&amp;T,
-BSD, Coherent, Minix, plan 9, busybox, toybox, and several more analyzed in
-the <a href=roadmap.html>roadmap</a>, and that's ignoring the implementations
-written for DOS or in assembly over the years). But I do care what
-Linux From Scratch expects, and if it's
-<a href=http://archive.linuxfromscratch.org/lfs-museum/7.6/LFS-BOOK-7.6-NOCHUNKS.html#ch-tools-gcc-pass1>calling mv -v</a>
-then I impelement mv -v
-even if <a href=http://landley.net/toybox/roadmap.html>posix hasn't got
-it</a>. And I don't know why "gnu counterparts" would describe this when
-util-linux isn't a gnu package, nor are info-zip, e2fsprogs, kmod, less,
-procps, shadow, sysklogd, vim, zlib, sudo, dhcpcd...</p>
-
-<a name="05-04-2015" /><a href="#05-04-2015"><hr><h2><b>April 5, 2015</b></h2></a>
+<hr><b>April 5, 2015</b>
 <p>Since <a href=https://android.googlesource.com/platform/external/toybox/>android</a> and
 <a href=https://git.tizen.org/cgit/platform/upstream/toybox.git>tizen</a>
 and <a href=https://github.com/kraj/meta-musl/tree/master/recipes-core/toybox>openembedded</a>
@@ -256,7 +18,7 @@ than the mercurial repository, I bit the bullet and switched the project's repo
 <a href=https://github.com/landley/toybox>to git</a>. Georgi's
 <a href=https://github.com/gfto/toybox>mirror</a> is now pulling from that.</p>
 
-<a name="25-02-2015" /><a href="#25-02-2015"><hr><h2><b>February 25, 2015</b></h2></a>
+<hr><b>February 25, 2015</b>
 <blockquote><p>"A common mistake that people make when trying to design
 something completely foolproof is to underestimate the ingenuity of
 complete fools."</p><p>- The Hitchhiker's Guide to the Galaxy.</p></blockquote>
@@ -376,7 +138,7 @@ supported, so stop using it.</p>
 <p>Fixed toy_exec() to detect when argc is in optargs, so we don't
 need a separate xexec_optargs().</p>
 
-<a name="18-02-2015" /><a href="#18-02-2015"><hr><h2><b>February 18, 2015</b></h2></a>
+<hr><b>February 18, 2015</b>
 <p>Dreamhost continues to be unable to make mailing list archives work, so
 here's <a href=http://www.mail-archive.com/toybox@lists.landley.net/>another
 list archive</a> with a less awkward interface than gmane.</p>
@@ -393,7 +155,7 @@ web archive, from Dec 15-Jan 3, and then another hole from Jan 16-Feb 18.
 The relevant messages are in both of the other archives. Here's hoping
 the chronic archive constipation problem won't happen a sixth time.</p>
 
-<a name="30-12-2014" /><a href="#30-12-2014"><hr><h2><b>December 30, 2014</b></h2></a>
+<hr><b>December 30, 2014</b>
 <p>Due to Dreamhost's <a href=http://landley.net/dreamhost.txt>ongoing</a>
 <a href=http://landley.net/dreamhost2.txt>inability</a> to make mailman
 work reliably, I've added a link to a backup web archive at
@@ -405,7 +167,7 @@ on the left.</p>
 
 <p>Update (January 27, 2015): they're <a href=https://twitter.com/landley/status/558428839462703104>still working on it</a>.</p>
 
-<a name="19-11-2014" /><a href="#19-11-2014"><hr><h2><b>November 19, 2014</b></h2></a>
+<hr><b>November 19, 2014</b>
 
 <blockquote><p>"This time it was right, it would work, and no one would have to get nailed to anything." - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
@@ -484,7 +246,7 @@ close each supplied filehandle itself.)</p>
 <p>The printf-style escape parsing ("\n" and friends) got factored out into
 a new unescape() function.</p>
 
-<a name="02-10-2014" /><a href="#02-10-2014"><hr><h2><b>October 2, 2014</b></h2></a>
+<hr><b>October 2, 2014</b>
 <blockquote><p>"There is an art, it says, or rather, a knack to flying.
 The knack lies in learning how to throw yourself at the ground and miss...
 Clearly, it is this second part, the missing, which presents the
@@ -635,7 +397,7 @@ sort on the host broke in non-C locales.</p>
 <p>Divya Kothari submitted tests for chmod, link, tar, bzcat, xzcat, zcat,
 and hostname. (And more, but that's all that's merged so far.)</p>
 
-<a name="07-07-2014" /><a href="#07-07-2014"><hr><h2><b>July 7, 2014</b></h2></a>
+<hr><b>July 7, 2014</b>
 <blockquote><p>"This planet has - or rather had - a problem, which was this:
 most of the people living on it were unhappy for pretty much of the time. Many
 solutions were suggested for this problem, but most of these were largely
@@ -757,7 +519,7 @@ bytes). The build infrastructure now notices duplicate commands (so if you
 cp toys/pending/command.c toys/other/command.c and forget to delete the
 first one, the build break is now more informative).</p>
 
-<a name="20-04-2014" /><a href="#20-04-2014"><hr><h2><b>April 20, 2014</b></h2></a>
+<hr><b>April 20, 2014</b>
 <blockquote><p>And to this end they built themselves a stupendous supercomputer
 which was so amazingly intelligent that even before the data banks
 had been connected up it had started from "I think therefore I am" and got as
@@ -843,7 +605,7 @@ of different kinds of simplicity, and why comments aren't a substitute for
 good code. The README no longer trails off into obvious unfinished confusion
 at the end. Each page on the website should now have its own title.</p>
 
-<a name="18-11-2013" /><a href="#18-11-2013"><hr><h2><b>November 18, 2013</b></h2></a>
+<hr><b>November 18, 2013</b>
 <blockquote><p>"Space," it says, "is big. Really big. You just won't believe how vastly, hugely, mindbogglingly big it is. I mean, you may think it's a long way down the street to the chemist's, but that's just peanuts to space." -
 The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
@@ -880,7 +642,7 @@ The "toynet.h" file got folded into toys.h since musl supports it and
 micromanging uClibc options isn't very interesting anymore. The test suite
 now uses scripts/single.sh when testing a single command.</p>
 
-<a name="17-09-2013" /><a href="#17-09-2013"><hr><h2><b>September 17, 2013</b></h2></a>
+<hr><b>September 17, 2013</b>
 <blockquote><p>"Think of a number," said the computer, "any number."
 Arthur told the computer the telephone number of King's Cross railway
 station passenger inquiries, on the grounds that it must have some function,
@@ -1009,13 +771,13 @@ delete sub and didn't exit with an error either. Neither was correct, rm
 should now be fixed.</p>
 
 <p>
-<a name="26-07-2013" /><a href="#26-07-2013"><hr><h2><b>July 26, 2013</b></h2></a>
+<hr><b>July 26, 2013</b>
 <p>Georgi Chorbadzhiyski maintains a <a href=https://github.com/gfto/toybox>git
 mirror</a> of the repository on github, automatically updated from the
 mercurial every 6 hours. The mirror is read only, but you can generate patches
 against it and post them to the list.</p>
 
-<a name="02-07-2013" /><a href="#02-07-2013"><hr><h2><b>July 2, 2013</b></h2></a>
+<hr><b>July 2, 2013</b>
 <blockquote><p>"Time is an illusion. Lunchtime doubly so." "Very deep. You
 should send that in to the Reader's Digest. They've got a page for people
 like you." -
@@ -1094,7 +856,7 @@ the GPL but "all copies must include this magic text blob" somehow don't?</p>
 or less public domain with a liability disclaimer, but we're still calling it
 BSD (sometimes "0 clause BSD") to avoid explaining.</p>
 
-<a name="21-03-2013" /><a href="#21-03-2013"><hr><h2><b>March 21, 2013</b></h2></a>
+<hr><b>March 21, 2013</b>
 <p>Video of my ELC talk
 "<a href=http://youtu.be/SGmtP5Lg_t0>Why is Toybox?</a>"
 is up on youtube. Related materials include the
@@ -1129,7 +891,7 @@ the ads, it's The Linux Foundation.)</p>
 </span>
 
 
-<a name="14-03-2013" /><a href="#14-03-2013"><hr><h2><b>March 14, 2013</b></h2></a>
+<hr><b>March 14, 2013</b>
 <blockquote><p>"Ford, you're turning into a penguin. Stop it." -
 The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
@@ -1152,7 +914,7 @@ should at least compile (although defconfig is still what's useful).</p>
 <p>Significant roadmap updates, checking several other multicall binaries
 (klibc, sash, sbase, s6...) to see what commands they include.</p>
 
-<a name="18-01-2013" /><a href="#18-01-2013"><hr><h2><b>January 18, 2013</b></h2></a>
+<hr><b>January 18, 2013</b>
 <blockquote><p>This must be Thursday. I never could get the hang of Thursdays. - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.4.3.tar.bz2>Toybox 0.4.3</a> is based on
@@ -1193,7 +955,7 @@ it now correctly detects "/trailing/slash/" which the previous code didn't.</p>
 disabled compiler optimization, so the binary size bloated a bit. It's back
 to -Os by default now.</p>
 
-<a name="15-12-2012" /><a href="#15-12-2012"><hr><h2><b>December 15, 2012</b></h2></a>
+<hr><b>December 15, 2012</b>
 <blockquote><p>"The major difference between a thing that might go wrong and a
 thing that cannot possibly go wrong is that when a thing that cannot possibly
 go wrong goes wrong it usually turns out to be impossible to get at or repair."
@@ -1244,7 +1006,7 @@ to do it Posix's way, which is more brittle and needs extra security checks,
 but am waiting for somebody to complain first. The default "ulimit -n" is 1024
 filehandles, so drilling down over 1000 nested subdirectories).</p>
 
-<a name="13-11-2012" /><a href="#13-11-2012"><hr><h2><b>November 13, 2012</b></h2></a>
+<hr><b>November 13, 2012</b>
 <blockquote><p>"Rule Six: The winning team shall be the first team that wins."
 - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
@@ -1308,7 +1070,7 @@ a separate <a href=oldnews.html>oldnews</a> page.</p>
 back now.</p>
 </span>
 
-<a name="23-07-2012" /><a href="#23-07-2012"><hr><h2><b>July 23, 2012</b></h2></a>
+<hr><b>July 23, 2012</b>
 <blockquote><p>"Ford", Arthur said. "There's an infinite number of monkeys
 out here who want to talk to us about this script for Hamlet they've worked
 out." - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
@@ -1333,7 +1095,7 @@ corresponding executable bit wasn't set, and worked around a longstanding
 glibc bug where static linking prevents stdout from automatically flushing
 pending output on exit.</p>
 
-<a name="25-06-2012" /><a href="#25-06-2012"><hr><h2><b>June 25, 2012</b></h2></a>
+<hr><b>June 25, 2012</b>
 <blockquote><p>"For a moment, nothing happened. Then, after a second or so, nothing continued to happen." - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.3.1.tar.bz2>Toybox 0.3.1</a> is based on commit
@@ -1349,7 +1111,7 @@ it is. The roadmap and documentation are a bit behind, and I've got ~40
 pending submissions to review. I need to catch up...</p>
 </span>
 
-<a name="12-06-2012" /><a href="#12-06-2012"><hr><h2><b>June 12, 2012</b></h2></a>
+<hr><b>June 12, 2012</b>
 <blockquote><p>"For instance, on the planet Earth, man had always assumed that
 he was more intelligent than dolphins because he had achieved so much - the
 wheel, New York, wars and so on - whilst all the dolphins had ever done was
@@ -1414,7 +1176,7 @@ yet, but if I wait until everything works we won't have a release before
 1.0, so here's a checkpoint.)</p>
 
 
-<a name="03-03-2012" /><a href="#03-03-2012"><hr><h2><b>March 3, 2012</b></h2></a>
+<hr><b>March 3, 2012</b>
 
 <blockquote><p>"They went unnoticed at Goonhilly, passed over Cape Canaveral
 without a blip, and Woomera and Jodrell Bank looked straight through them.
@@ -1454,7 +1216,7 @@ dirname, unshare, and various infrastructure tweaks, but it took me 3 months
 and those guys did their stuff in a week or so.)</p>
 
 
-<a name="12-02-2012" /><a href="#12-02-2012"><hr><h2><b>February 12, 2012</b></h2></a>
+<hr><b>February 12, 2012</b>
 <blockquote><p>
 "for though it has many omissions and contains much that is apocryphal, or at
 least wildly inaccurate, it scores over the older, more pedestrian work in two
@@ -1471,8 +1233,7 @@ patches pending on the mailing list I need to review and merge.</p>
 <p>More to come...</p>
 
 <hr>
-<a name="15-11-2011" /><a href="#15-11-2011"><hr><h2><b>November 15, 2011</b></h2></a>
-- Back from the dead, Toybox is now under a 2
+<p><b>November 15, 2011</b> - Back from the dead, Toybox is now under a 2
 clause BSD license, and aiming to become the default command line
 implementation of Android systems everywhere.</p>
 
index e5105b8..bba08b1 100755 (executable)
@@ -244,13 +244,15 @@ sendevent start stop top uptime watchprops
 <h3>Other Android core commands</h3>
 
 <p>Other than the toolbox directory, the currently interesting
-subdirectories in the core repository are init,
-logcat, logwrapper, reboot, and run-as.</p>
+subdirectories in the core repository are gpttool, init,
+logcat, logwrapper, mkbootimg, reboot, and run-as.</p>
 
 <ul>
+<li><b>gpttool</b> - subset of fdisk</li>
 <li><b>init</b> - Android's PID 1</li>
 <li><b>logcat</b> - read android log format</li>
 <li><b>logwrapper</b> - redirect stdio to android log</li>
+<li><b>mkbootimg</b> - create signed boot image</li>
 <li><b>reboot</b> - Android's reboot(1)</li>
 <li><b>run-as</b> - subset of sudo</li>
 </ul>
@@ -259,13 +261,17 @@ logcat, logwrapper, reboot, and run-as.</p>
 different user interface. We may want to provide that interface, but
 implementing the full commands (fdisk, init, and sudo) come first.</p>
 
+<p>Also, gpttool and mkbootimg are install tools.
+These aren't a priority if android wants to use its own
+bespoke code to install itself.</p>
+
 <h3>Analysis</h3>
 
 <p>For reference, combining everything listed above, we get:</p>
 
 <blockquote><b>
-dd du df getevent iftop init ioctl ionice
-log logcat logwrapper ls lsof mount nandread
+dd du df getevent gpttool iftop init ioctl ionice
+log logcat logwrapper ls lsof mkbootimg mount nandread
 newfs_msdos ps prlimit reboot renice run-as
 sendevent start stop top uptime watchprops
 </b></blockquote>