Merge "Regenerate generated files after upstream sync."
diff --git a/lib/lib.c b/lib/lib.c
index 490235f..ade0786 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -512,8 +512,7 @@
   struct stat statbuf;
   int fd;
 
-  *tempname = xstrndup(name, strlen(name)+6);
-  strcat(*tempname,"XXXXXX");
+  *tempname = xmprintf("%s%s", name, "XXXXXX");
   if(-1 == (fd = mkstemp(*tempname))) error_exit("no temp file");
   if (!tempfile2zap) sigatexit(tempfile_handler);
   tempfile2zap = *tempname;
diff --git a/scripts/make.sh b/scripts/make.sh
index df74011..1cbe5e0 100755
--- a/scripts/make.sh
+++ b/scripts/make.sh
@@ -49,7 +49,7 @@
 
   echo "USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT))" > generated/newtoys.h
   sed -n -e 's/^USE_[A-Z0-9_]*(/&/p' toys/*/*.c \
-	| sed 's/\(.*TOY(\)\([^,]*\),\(.*\)/\2 \1\2,\3/' | sort -k 1,1 \
+	| sed 's/\(.*TOY(\)\([^,]*\),\(.*\)/\2 \1\2,\3/' | sort -s -k 1,1 \
 	| sed 's/[^ ]* //'  >> generated/newtoys.h &&
   sed -n -e 's/.*(NEWTOY(\([^,]*\), *\(\("[^"]*"[^,]*\)*\),.*/#define OPTSTR_\1\t\2/p' \
     generated/newtoys.h > generated/oldtoys.h || exit 1
@@ -173,7 +173,7 @@
 # If no pair (because command's disabled in config), use " " for flags
 # so allflags can define the appropriate zero macros.
 
-done | sort | sed -n 's/ A / /;t pair;h;s/\([^ ]*\).*/\1 " "/;x;b single;:pair;h;n;:single;s/[^ ]* B //;H;g;s/\n/ /;p' |\
+done | sort -s | sed -n 's/ A / /;t pair;h;s/\([^ ]*\).*/\1 " "/;x;b single;:pair;h;n;:single;s/[^ ]* B //;H;g;s/\n/ /;p' |\
 generated/mkflags > generated/flags.h || exit 1
 
 # Extract global structure definitions and flag definitions from toys/*/*.c
diff --git a/tests/sed.test b/tests/sed.test
index 789a1a5..dfc7602 100644
--- a/tests/sed.test
+++ b/tests/sed.test
@@ -75,6 +75,8 @@
 testing "sed c {range}" "sed -e '2,4{c blah' -e '}'" \
 	"one\nblah\nblah\nblah\nfive\nsix" \
         "" "one\ntwo\nthree\nfour\nfive\nsix"
+testing "sed c multiple continuation" \
+	"sed -e 'c\\' -e 'two\\' -e ''" "two\n\n" "" "hello"
 testing "sed D further processing depends on whether line is blank" \
 	"sed -e '/one/,/three/{' -e 'i meep' -e'N;2D;}'" \
 	"meep\nmeep\ntwo\nthree\n" "" "one\ntwo\nthree\n"
diff --git a/toys/other/catv.c b/toys/other/catv.c
deleted file mode 100644
index 62520c4..0000000
--- a/toys/other/catv.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* cat -v implementation for toybox
- *
- * Copyright (C) 2006, 2007 Rob Landley <rob@landley.net>
- *
- * See "Cat -v considered harmful" at
- *   http://cm.bell-labs.com/cm/cs/doc/84/kp.ps.gz
-
-USE_CATV(NEWTOY(catv, "vte", TOYFLAG_USR|TOYFLAG_BIN))
-
-config CATV
-  bool "catv"
-  default y
-  help
-    usage: catv [-evt] [filename...]
-
-    Display nonprinting characters as escape sequences. Use M-x for
-    high ascii characters (>127), and ^x for other nonprinting chars.
-
-    -e	Mark each newline with $
-    -t	Show tabs as ^I
-    -v	Don't use ^x or M-x escapes.
-*/
-
-#define FOR_catv
-#include "toys.h"
-
-// Callback function for loopfiles()
-
-static void do_catv(int fd, char *name)
-{
-  for(;;) {
-    int i, len;
-
-    len = read(fd, toybuf, sizeof(toybuf));
-    if (len < 0) toys.exitval = EXIT_FAILURE;
-    if (len < 1) break;
-    for (i=0; i<len; i++) {
-      char c=toybuf[i];
-
-      if (c > 126 && (toys.optflags & FLAG_v)) {
-        if (c > 127) {
-          printf("M-");
-          c -= 128;
-        }
-        if (c == 127) {
-          printf("^?");
-          continue;
-        }
-      }
-      if (c < 32) {
-        if (c == 10) {
-          if (toys.optflags & FLAG_e) xputc('$');
-        } else if (toys.optflags & (c==9 ? FLAG_t : FLAG_v)) {
-          printf("^%c", c+'@');
-          continue;
-        }
-      }
-      xputc(c);
-    }
-  }
-}
-
-void catv_main(void)
-{
-  toys.optflags ^= FLAG_v;
-  loopfiles(toys.optargs, do_catv);
-}
diff --git a/toys/pending/getenforce.c b/toys/pending/getenforce.c
new file mode 100644
index 0000000..ce43f52
--- /dev/null
+++ b/toys/pending/getenforce.c
@@ -0,0 +1,31 @@
+/* getenforce.c - Get the current SELinux mode
+ *
+ * Copyright 2014 The Android Open Source Project
+
+USE_GETENFORCE(NEWTOY(getenforce, "", TOYFLAG_USR|TOYFLAG_SBIN))
+
+config GETENFORCE
+  bool "getenforce"
+  default n
+  help
+    usage: getenforce
+
+    Shows whether SELinux is disabled, enforcing, or permissive.
+*/
+
+#define FOR_getenforce
+#include "toys.h"
+#include <selinux/selinux.h>
+
+void getenforce_main(void)
+{
+  if (!is_selinux_enabled())
+    printf("Disabled\n");
+  else {
+    int ret = security_getenforce();
+    if (ret == -1)
+      perror_exit("Couldn't get enforcing status");
+    else
+      printf(ret ? "Enforcing\n" : "Permissive\n");
+  }
+}
diff --git a/toys/pending/setenforce.c b/toys/pending/setenforce.c
new file mode 100644
index 0000000..6953f5b
--- /dev/null
+++ b/toys/pending/setenforce.c
@@ -0,0 +1,36 @@
+/* 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/cat.c b/toys/posix/cat.c
index 3644c4f..5b4ab71 100644
--- a/toys/posix/cat.c
+++ b/toys/posix/cat.c
@@ -3,8 +3,12 @@
  * Copyright 2006 Rob Landley <rob@landley.net>
  *
  * See http://opengroup.org/onlinepubs/9699919799/utilities/cat.html
+ *
+ * And "Cat -v considered harmful" at
+ *   http://cm.bell-labs.com/cm/cs/doc/84/kp.ps.gz
 
-USE_CAT(NEWTOY(cat, "u", TOYFLAG_BIN))
+USE_CAT(NEWTOY(cat, "u"USE_CAT_V("vte"), TOYFLAG_BIN))
+#USE_CATV(NEWTOY(catv, USE_CATV("vte"), TOYFLAG_USR|TOYFLAG_BIN))
 
 config CAT
   bool "cat"
@@ -16,19 +20,76 @@
     Filename "-" is a synonym for stdin.
 
     -u	Copy one byte at a time (slow).
+
+config CAT_V
+  bool "cat -etv"
+  default y
+  depends on CAT
+  help
+    usage: cat [-evt]
+
+    Display nonprinting characters as escape sequences. Use M-x for
+
+    -e	Mark each newline with $
+    -t	Show tabs as ^I
+    -v	Display nonprinting characters as escape sequences. Use M-x for
+    	high ascii characters (>127), and ^x for other nonprinting chars.
 */
 
+/*
+todo:
+
+config CATV
+  bool "catv"
+  default y
+  depends on !CAT_V
+  help
+    usage: catv [-evt] [filename...]
+
+    Display nonprinting characters as escape sequences. Use M-x for
+    high ascii characters (>127), and ^x for other nonprinting chars.
+
+    -e  Mark each newline with $
+    -t  Show tabs as ^I
+    -v  Don't use ^x or M-x escapes.
+*/
+
+#define FOR_cat
 #include "toys.h"
 
 static void do_cat(int fd, char *name)
 {
-  int len, size=toys.optflags ? 1 : sizeof(toybuf);
+  int i, len, size=(toys.optflags & FLAG_u) ? 1 : sizeof(toybuf);
 
-  for (;;) {
+  for(;;) {
     len = read(fd, toybuf, size);
-    if (len<0) perror_msg("%s",name);
-    if (len<1) break;
-    xwrite(1, toybuf, len);
+    if (len < 0) toys.exitval = EXIT_FAILURE;
+    if (len < 1) break;
+    if (CFG_CAT_V && (toys.optflags&~FLAG_u)) {
+      for (i=0; i<len; i++) {
+        char c=toybuf[i];
+
+        if (c > 126 && (toys.optflags & FLAG_v)) {
+          if (c > 127) {
+            printf("M-");
+            c -= 128;
+          }
+          if (c == 127) {
+            printf("^?");
+            continue;
+          }
+        }
+        if (c < 32) {
+          if (c == 10) {
+            if (toys.optflags & FLAG_e) xputc('$');
+          } else if (toys.optflags & (c==9 ? FLAG_t : FLAG_v)) {
+            printf("^%c", c+'@');
+            continue;
+          }
+        }
+        xputc(c);
+      }
+    } else xwrite(1, toybuf, len);
   }
 }
 
@@ -36,3 +97,15 @@
 {
   loopfiles(toys.optargs, do_cat);
 }
+
+//todo:
+//void catv_main(void)
+//{
+//  toys.optflags ^= FLAG_v;
+//  loopfiles(toys.optargs, do_catv);
+//}
+
+// The common infrastructure is testing FLAG_h which is only defined in cat
+// context (not catv), but catv can't use cat's flag context if cat is disabled
+// and its flags are zero. Need to upgrade flag parsing infrastructure so
+// defining FORCE_FLAGS along with FOR_command doesn't zero unused flag macros.
diff --git a/toys/pending/sed.c b/toys/posix/sed.c
similarity index 93%
rename from toys/pending/sed.c
rename to toys/posix/sed.c
index 8703806..e9f76d8 100644
--- a/toys/pending/sed.c
+++ b/toys/posix/sed.c
@@ -11,7 +11,7 @@
 
 config SED
   bool "sed"
-  default n
+  default y
   help
     usage: sed [-inr] [-e SCRIPT]...|SCRIPT [-f SCRIPT_FILE]... [FILE...]
 
@@ -83,9 +83,9 @@
 
       H  Remember this line (appending to remembered line, if any)
 
-      l  Print this line, escaping \abfrtv (but leaving \n as a newline),
-         using octal escapes for other nonprintable characters, and
-         wrapping lines to terminal width with a backslash and newline
+      l  Print line, escaping \abfrtv (but not newline), octal escaping other
+         nonprintable characters, wrapping lines to terminal width with a
+         backslash, and appending $ to actual end of line.
 
       n  Print default output and read next line, replacing current line
          (If no next line available, quit processing script)
@@ -175,6 +175,7 @@
   void *restart, *lastregex;
   long nextlen, rememberlen, count;
   int fdout, noeol;
+  unsigned xx;
 )
 
 struct step {
@@ -363,7 +364,7 @@
     if (c=='a' || c=='r') {
       struct append *a = xzalloc(sizeof(struct append));
       a->str = logrus->arg1+(char *)logrus;
-      a->file = c== 'r';
+      a->file = c=='r';
       dlist_add_nomalloc((void *)&append, (void *)a);
     } else if (c=='b' || c=='t' || c=='T') {
       int t = tea;
@@ -425,8 +426,31 @@
     } else if (c=='i') {
       str = logrus->arg1+(char *)logrus;
       emit(str, strlen(str), 1);
-//    } else if (c=='l') {
-//      error_exit("todo: l");
+    } else if (c=='l') {
+      int i, x, off;
+
+      if (!TT.xx) {
+        terminal_size(&TT.xx, 0);
+        if (!TT.xx) TT.xx = 80;
+        if (TT.xx > sizeof(toybuf)-10) TT.xx = sizeof(toybuf)-10;
+        if (TT.xx > 4) TT.xx -= 4;
+      }
+
+      for (i = off = 0; i<len; i++) {
+        if (off >= TT.xx) {
+          toybuf[off++] = '\\';
+          emit(toybuf, off, 1);
+          off = 0;
+        }
+        x = stridx("\\\a\b\f\r\t\v", line[i]);
+        if (x != -1) {
+          toybuf[off++] = '\\';
+          toybuf[off++] = "\\abfrtv"[x];
+        } else if (line[i] >= ' ') toybuf[off++] = line[i];
+        else off += sprintf(toybuf+off, "\\%03o", line[i]);
+      }
+      toybuf[off++] = '$';
+      emit(toybuf, off, 1);
     } else if (c=='n') {
       TT.restart = logrus->next;
 
@@ -603,12 +627,15 @@
     struct append *a = append->next;
 
     if (append->file) {
-      int fd = xopen(append->str, O_RDONLY);
+      int fd = open(append->str, O_RDONLY);
 
       // Force newline if noeol pending
-      emit(0, 0, 0);
-      xsendfile(fd, TT.fdout);
-      close(fd);
+      if (fd != -1) {
+        if (TT.noeol) xwrite(TT.fdout, "\n", 1);
+        TT.noeol = 0;
+        xsendfile(fd, TT.fdout);
+        close(fd);
+      }
     } else emit(append->str, strlen(append->str), 1);
     free(append);
     append = a;
@@ -702,7 +729,8 @@
 
       // Check escaped end delimiter before printf style escapes.
       if (from[1] == d) from++;
-      else if (from[1]!='\\') {
+      else if (from[1]=='\\') *(to++) = *(from++);
+      else {
         char c = unescape(from[1]);
 
         if (c) {
@@ -728,6 +756,7 @@
   int i;
 
   // Append additional line to pattern argument string?
+  // We temporarily repurpose "hit" to indicate line continuations
   if (corwin && corwin->prev->hit) {
     // Remove half-finished entry from list so remalloc() doesn't confuse it
     TT.pattern = TT.pattern->prev;
@@ -827,7 +856,7 @@
       for (line++; *line; line++) {
         long l;
 
-        if (isspace(*line)) continue;
+        if (isspace(*line) && *line != '\n') continue;
 
         if (0 <= (l = stridx("igp", *line))) corwin->sflags |= 1<<l;
         else if (!(corwin->sflags>>3) && 0<(l = strtol(line, &line, 10))) {
@@ -892,33 +921,30 @@
       reg = extend_string((void *)&corwin, s, reg-(char*)corwin, len);
       free(s);
     } else if (strchr("abcirtTw:", c)) {
-      int end, class;
+      int end;
 
       // Trim whitespace from "b ;" and ": blah " but only first space in "w x "
 
-      while (isspace(*line)) {
-        if (!strchr("btT", c) || *line != '\n') line++;
-        else break;
-      }
+      while (isspace(*line) && *line != '\n') line++;
 append:
-      class = !strchr("btT:", c);
-      end = strcspn(line, class ? "\n" : "; \t\r\n\v\f");
-
-      if (!end) {
-        if (!strchr("btT", c)) break;
-        continue;
+      if (!(end = strcspn(line, strchr("btT:", c) ? "; \t\r\n\v\f" : "\n"))) {
+        if (strchr("btT", c)) continue;
+        else if (!corwin->arg1) break;
       }
 
       // Extend allocation to include new string. We use offsets instead of
       // pointers so realloc() moving stuff doesn't break things. Do it
       // here instead of toybuf so there's no maximum size.
       if (!corwin->arg1) corwin->arg1 = reg - (char*)corwin;
-      reg = extend_string((void *)&corwin, line, reg - (char *)corwin, end); 
+      else if ((corwin+1) != (void *)reg) *(reg++) = '\n';
+      reg = extend_string((void *)&corwin, line, reg - (char *)corwin, end);
+
       line += end;
 
       // Line continuation? (Two slightly different input methods, -e with
       // embedded newline vs -f line by line. Must parse both correctly.)
-      if (class && line[-1] == '\\') {
+      if (!strchr("btT:", c) && line[-1] == '\\') {
+        // reg is next available space, so reg[-1] is the null terminator
         reg[-2] = 0;
         if (*line && line[1]) {
           reg -= 2;
diff --git a/www/roadmap.html b/www/roadmap.html
index ba128f2..213ca6f 100755
--- a/www/roadmap.html
+++ b/www/roadmap.html
@@ -33,6 +33,7 @@
 <li><a href=#sigh>Linux "Standard" Base</a></li>
 <li><a href=#dev_env>Development Environment</a></li>
 <li><a href=#android>Android Toolbox</a></li>
+<li><a href=#tizen>Tizen Core</a></li>
 <li>Miscelaneous: <a href=#klibc>klibc</a>, <a href=#glibc>glibc</a>,
 <a href=#sash>sash</a>, <a href=#sbase>sbase</a>, <a href=#s6>s6</a>...</li>
 </ul>
@@ -327,6 +328,31 @@
 setprop smd start stop top uptime vmstat watchprops watchdogd wipe
 </b></blockquote>
 
+<hr />
+<h2><a name=tizen /><a href="#tizen">Use case: Tizen Core</a></h2>
+
+<p>The Tizen project has expressed a desire to eliminate GPLv3 software
+from its core system, and is installing toybox as
+<a href=https://wiki.tizen.org/wiki/Toybox>part of this process</a>.</p>
+
+<p>They have a fairly long list of new commands they'd like to see in toybox:</p>
+
+<blockquote><b>
+<span id=tizen>
+arch base64 users dir vdir unexpand shred join csplit
+hostid nproc runcon sha224 sha256 sha384 sha512 sha3 mkfs.vfat fsck.vfat 
+dosfslabel uname stdbuf pinky diff3 sdiff zcmp zdiff zegrep zfgrep zless zmore
+</span>
+</blockquote>
+
+<p>In addition, they'd like to use several commands currently in pending:</p>
+
+<blockquote><b>
+<span id=tizen>
+tar diff printf wget rsync fdisk vi less tr test stty fold expr dd
+</span>
+</b></blockquote>
+
 <hr /><a name=klibc />
 <h2>klibc:</h2>