Merge remote-tracking branch 'toybox/master' into HEAD
diff --git a/configure b/configure
index 21d56f3..5831e1a 100644
--- a/configure
+++ b/configure
@@ -7,7 +7,7 @@
 
 # CFLAGS and OPTIMIZE are different so you can add extra CFLAGS without
 # disabling default optimizations
-[ -z "$CFLAGS" ] && CFLAGS="-Wall -Wundef -Wno-char-subscripts"
+[ -z "$CFLAGS" ] && CFLAGS="-Wall -Wundef -Wno-char-subscripts -Wno-string-plus-int"
 # Required for our expected ABI. we're 8-bit clean thus "char" must be unsigned.
 CFLAGS="$CFLAGS -funsigned-char"
 [ -z "$OPTIMIZE" ] && OPTIMIZE="-Os -ffunction-sections -fdata-sections -fno-asynchronous-unwind-tables"
diff --git a/kconfig/README b/kconfig/README
new file mode 100644
index 0000000..8809bbf
--- /dev/null
+++ b/kconfig/README
@@ -0,0 +1,26 @@
+This is a snapshot of linux 2.6.12 kconfig as washed through busybox and
+further modified by Rob Landley.
+
+Way back when I tried to push my local changes to kconfig upstream
+in 2005 https://lwn.net/Articles/161086/
+and 2006 http://lkml.iu.edu/hypermail/linux/kernel/0607.0/1805.html
+and 2007 http://lkml.iu.edu/hypermail/linux/kernel/0707.1/1741.html
+each of which spawned long "I think you should go do this and this and this
+but I'm not going to lift a finger personally" threads from the kernel
+developers. Twice I came back a year later to see if there was any interest
+in what I _had_ done, and the third thread was the longest of the lot but
+no code was merged as a result.
+
+*shrug* That's the linux-kernel community for you. I had an easier time
+than the author of squashfs, who spent 5 years actively trying to get his code
+merged, finally quitting his job to spend an unpaid year working on upstreaming
+squashfs _after_ after every major Linux distro had been locally carrying it
+for years. No really, here's where he wrote about it himself:
+
+https://lwn.net/Articles/563578/
+
+This code is _going_away_. Rewriting it is low priority, but removing it is a
+checklist item for the 1.0 toybox release. This directory contains the only
+GPL code left in the tree, and none of its code winds up in the resulting
+binary. It's just an editor that reads our Config.in files to update the top
+level .config file; you can edit they by hand if you really want to.
diff --git a/kconfig/zconf.hash.c_shipped b/kconfig/zconf.hash.c_shipped
index 47c8b5b..0287aa3 100644
--- a/kconfig/zconf.hash.c_shipped
+++ b/kconfig/zconf.hash.c_shipped
@@ -159,7 +159,7 @@
     "enable"
   };
 #define kconf_id_strings ((const char *) &kconf_id_strings_contents)
-#ifdef __GNUC__
+#if defined(__GNUC__) && __STDC_VERSION__ < 199901L
 __inline
 #endif
 struct kconf_id *
diff --git a/toys/pending/getenforce.c b/toys/android/getenforce.c
similarity index 65%
rename from toys/pending/getenforce.c
rename to toys/android/getenforce.c
index ce43f52..465452e 100644
--- a/toys/pending/getenforce.c
+++ b/toys/android/getenforce.c
@@ -6,7 +6,8 @@
 
 config GETENFORCE
   bool "getenforce"
-  default n
+  default y
+  depends on TOYBOX_SELINUX
   help
     usage: getenforce
 
@@ -15,17 +16,14 @@
 
 #define FOR_getenforce
 #include "toys.h"
-#include <selinux/selinux.h>
 
 void getenforce_main(void)
 {
-  if (!is_selinux_enabled())
-    printf("Disabled\n");
+  if (!is_selinux_enabled()) puts("Disabled");
   else {
     int ret = security_getenforce();
-    if (ret == -1)
-      perror_exit("Couldn't get enforcing status");
-    else
-      printf(ret ? "Enforcing\n" : "Permissive\n");
+
+    if (ret == -1) perror_exit("Couldn't get enforcing status");
+    else puts(ret ? "Enforcing" : "Permissive");
   }
 }
diff --git a/toys/android/load_policy.c b/toys/android/load_policy.c
new file mode 100644
index 0000000..aa59f36
--- /dev/null
+++ b/toys/android/load_policy.c
@@ -0,0 +1,37 @@
+/* load_policy.c - Load a policy file
+ *
+ * Copyright 2015 The Android Open Source Project
+
+USE_LOAD_POLICY(NEWTOY(load_policy, "<1>1", TOYFLAG_USR|TOYFLAG_SBIN))
+
+config LOAD_POLICY
+  bool "load_policy"
+  depends on TOYBOX_SELINUX
+  default y
+  help
+    usage: load_policy FILE
+
+    Load the specified policy file.
+*/
+
+#define FOR_load_policy
+#include "toys.h"
+
+void load_policy_main(void)
+{
+  char *path = *toys.optargs;
+  char *policy_data = 0;
+  off_t policy_len;
+  int fd;
+
+  if ((fd = open(path, O_RDONLY)) != -1) {
+    policy_len = fdlength(fd);
+    policy_data = mmap(0, policy_len, PROT_READ, MAP_PRIVATE, fd, 0);
+    close(fd);
+  }
+
+  if (!policy_data || security_load_policy(policy_data, policy_len) < 0)
+    perror_exit("Couldn't %s %s: %s", policy_data ? "load" : "read", path);
+
+  munmap(policy_data, policy_len);
+}
diff --git a/toys/android/setenforce.c b/toys/android/setenforce.c
new file mode 100644
index 0000000..6895746
--- /dev/null
+++ b/toys/android/setenforce.c
@@ -0,0 +1,32 @@
+/* setenforce.c - Set the current SELinux mode
+ *
+ * Copyright 2014 The Android Open Source Project
+
+USE_SETENFORCE(NEWTOY(setenforce, "<1", TOYFLAG_USR|TOYFLAG_SBIN))
+
+config SETENFORCE
+  bool "setenforce"
+  default y
+  depends on TOYBOX_SELINUX
+  help
+    usage: setenforce [enforcing|permissive|1|0]
+
+    Sets whether SELinux is enforcing (1) or permissive (0).
+*/
+
+#define FOR_setenforce
+#include "toys.h"
+
+void setenforce_main(void)
+{
+  char *new = *toys.optargs;
+  int state, ret;
+
+  if (!is_selinux_enabled()) error_exit("SELinux is disabled");
+  else if (!strcmp(new, "1") || !strcasecmp(new, "enforcing")) state = 1;
+  else if (!strcmp(new, "0") || !strcasecmp(new, "permissive")) state = 0;
+  else error_exit("Invalid state: %s", new);
+
+  ret = security_setenforce(state);
+  if (ret == -1) perror_msg("Couldn't set enforcing status to '%s'", new);
+}
diff --git a/toys/pending/setenforce.c b/toys/pending/setenforce.c
deleted file mode 100644
index 6953f5b..0000000
--- a/toys/pending/setenforce.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* setenforce.c - Set the current SELinux mode
- *
- * Copyright 2014 The Android Open Source Project
-
-USE_SETENFORCE(NEWTOY(setenforce, "<1", TOYFLAG_USR|TOYFLAG_SBIN))
-
-config SETENFORCE
-  bool "setenforce"
-  default n
-  help
-    usage: setenforce [enforcing|permissive|1|0]
-
-    Sets whether SELinux is enforcing (1) or permissive (0).
-*/
-
-#define FOR_setenforce
-#include "toys.h"
-#include <selinux/selinux.h>
-
-void setenforce_main(void)
-{
-  char *state_str = *toys.optargs;
-  int state;
-  if (!is_selinux_enabled())
-    error_exit("SELinux is disabled");
-  else if (!strcmp(state_str, "1") || !strcasecmp(state_str, "enforcing"))
-    state = 1;
-  else if (!strcmp(state_str, "0") || !strcasecmp(state_str, "permissive"))
-    state = 0;
-  else
-    error_exit("Invalid state: %s", state_str);
-
-  int ret = security_setenforce(state);
-  if (ret == -1)
-    perror_msg("Couldn't set enforcing status to '%s'", state_str);
-}
diff --git a/toys/posix/tail.c b/toys/posix/tail.c
index e92c044..41d4633 100644
--- a/toys/posix/tail.c
+++ b/toys/posix/tail.c
@@ -4,7 +4,7 @@
  *
  * See http://opengroup.org/onlinepubs/9699919799/utilities/tail.html
 
-USE_TAIL(NEWTOY(tail, "fc-n-[-cn]", TOYFLAG_BIN))
+USE_TAIL(NEWTOY(tail, "?fc-n-[-cn]", TOYFLAG_BIN))
 
 config TAIL
   bool "tail"
@@ -17,7 +17,7 @@
 
     -n	output the last NUMBER lines (default 10), +X counts from start.
     -c	output the last NUMBER bytes, +NUMBER counts from start
-    -f	follow FILE(s), waiting for more data to be appended
+    #-f	follow FILE(s), waiting for more data to be appended [TODO]
 
 config TAIL_SEEK
   bool "tail seek support"
@@ -213,10 +213,22 @@
 
 void tail_main(void)
 {
-  // if nothing specified, default -n to -10
-  if (!(toys.optflags&(FLAG_n|FLAG_c))) TT.lines = -10;
+  char **args = toys.optargs;
 
-  loopfiles(toys.optargs, do_tail);
+  if (!(toys.optflags&(FLAG_n|FLAG_c))) {
+    char *arg = *args;
+
+    // handle old "-42" style arguments
+    if (arg && *arg == '-' && arg[1]) {
+      TT.lines = atolx(*(args++));
+      toys.optc--;
+    }
+
+    // if nothing specified, default -n to -10
+    TT.lines = -10;
+  }
+
+  loopfiles(args, do_tail);
 
   // do -f stuff
 }