Update status and roadmap pages, and status page generator script.
diff --git a/scripts/mkstatus.py b/scripts/mkstatus.py
index ec225ed..cb34d45 100755
--- a/scripts/mkstatus.py
+++ b/scripts/mkstatus.py
@@ -15,10 +15,14 @@
     arr.extend(i)
   return ret,arr
 
-stuff,blah=readit(["sed","-n", 's/<span id=\\([a-z_]*\\)>/\\1 /;t good;d;:good;h;:loop;n;s@</span>@@;t out;H;b loop;:out;g;s/\\n/ /g;p', "www/roadmap.html", "www/status.html"])
+# Run sed on roadmap and status pages to get command lists, and run toybox too
+# This gives us a dictionary of types, each with a list of commands
 
+stuff,blah=readit(["sed","-n", 's/<span id=\\([a-z_]*\\)>/\\1 /;t good;d;:good;h;:loop;n;s@</span>@@;t out;H;b loop;:out;g;s/\\n/ /g;p', "www/roadmap.html", "www/status.html"])
 blah,toystuff=readit(["./toybox"])
 
+# Create reverse mappings: command is in which
+
 reverse={}
 for i in stuff:
   for j in stuff[i]:
@@ -39,21 +43,36 @@
 outfile=open("www/status.gen", "w")
 outfile.write("<a name=all><h2><a href=#all>All commands</a></h2><blockquote><p>\n")
 
+conv = [("posix", '<a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/%s.html">%%s</a>', "[%s]"),
+        ("lsb", '<a href="http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/%s.html">%%s</a>', '&lt;%s&gt;'),
+        ("development", '<a href="http://linux.die.net/man/1/%s">%%s</a>', '(%s)'),
+        ("toolbox", "", '{%s}'), ("klibc_cmd", "", '=%s='),
+        ("sash_cmd", "", '#%s#'), ("sbase_cmd", "", '@%s@'),
+        ("beastiebox_cmd", "", '*%s*'),
+        ("request", '<a href="http://linux.die.net/man/1/%s">%%s</a>', '+%s+')]
+
+
+def categorize(reverse, i, skippy=""):
+  linky = "%s"
+  out = i
+
+  if skippy: types = filter(lambda a: a != skippy, reverse[i])
+  else: types = reverse[i]
+
+  for j in conv:
+    if j[0] in types:
+      if j[1]: linky = j[1] % i
+      out = j[2] % out
+      if not skippy: break
+  if (not skippy) and out == i:
+    sys.stderr.write("unknown %s %s\n" % (i,reverse[i]))
+
+  return linky % out
+
 blah=list(reverse)
 blah.sort()
 for i in blah:
-  out=i
-  if "posix" in reverse[i]: out='[<a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/%s.html">%s</a>]' % (i,out)
-  elif "lsb" in reverse[i]: out='&lt;<a href="http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/%s.html">%s</a>&gt;' % (i,out)
-  elif "development" in reverse[i]: out='(<a href="http://linux.die.net/man/1/%s">%s</a>)' % (i,out)
-  elif "toolbox" in reverse[i]: out='{%s}' % out
-  elif "klibc_cmd" in reverse[i]: out='=%s=' % out
-  elif "sash_cmd" in reverse[i]: out='#%s#' % out
-  elif "sbase_cmd" in reverse[i]: out='@%s@' % out
-  elif "beastiebox_cmd" in reverse[i]: out='*%s*' % out
-  elif "request" in reverse[i]: out='+<a href="http://linux.die.net/man/1/%s">%s</a>+' % (i,out)
-  elif "ready" in reverse[i]: pass
-  else: sys.stderr.write("unknown %s %s\n" % (i, reverse[i]))
+  out=categorize(reverse, i)
   if "ready" in reverse[i] or "pending" in reverse[i]:
     done.append(out)
     out='<strike>%s</strike>' % out
@@ -66,3 +85,22 @@
 
 outfile.write("<a name=todo><h2><a href=#todo>TODO</a></h2><blockquote><p>%s</p></blockquote>\n" % "\n".join(pending))
 outfile.write("<a name=done><h2><a href=#done>Done</a></h2><blockquote><p>%s</p></blockquote>\n" % "\n".join(done))
+
+outfile.write("<hr><h2>Categories of remaining todo items</h2>")
+
+for i in stuff:
+  todo = []
+
+  for j in stuff[i]:
+    if "ready" in reverse[j]: continue
+    else: todo.append(categorize(reverse,j,i))
+
+  if todo:
+    k = i
+    for j in conv:
+      if j[0] == i:
+        k = j[2] % i
+
+    outfile.write("<a name=%s><h2><a href=#%s>%s<a></h2><blockquote><p>" % (i,i,k))
+    outfile.write(" ".join(todo))
+    outfile.write("</p></blockquote>\n")
diff --git a/www/roadmap.html b/www/roadmap.html
index 94df830..203b8d2 100755
--- a/www/roadmap.html
+++ b/www/roadmap.html
@@ -399,7 +399,7 @@
 <p>So the list of things actually in klibc are:</p>
 
 <blockquote><b>
-<span id=klibc_cmd />
+<span id=klibc_cmd>
 cat chroot dmesg false kill ln losetup ls mkdir mkfifo readlink rm switch_root
 sleep sync true uname
 
@@ -463,7 +463,7 @@
 implemented:</p>
 
 <blockquote><p>
-<span id=sbase_cmd />
+<span id=sbase_cmd>
 basename cat chmod chown cksum cmp cp date dirname echo false fold grep head
 kill ln ls mc mkdir mkfifo mv nl nohup pwd rm seq sleep sort tail tee test
 touch true tty uname uniq wc yes
@@ -473,7 +473,7 @@
 <p>And has a TODO list:</p>
 
 <blockquote><p>
-<span id=sbase_cmd />
+<span id=sbase_cmd>
 cal chgrp chvt comm cut df diff du env expand expr id md5sum nice paste
 printenv printf readlink rmdir seq sha1sum split sync test tr unexpand unlink
 who
diff --git a/www/status.html b/www/status.html
index 3e9adb3..c89727e 100755
--- a/www/status.html
+++ b/www/status.html
@@ -8,16 +8,17 @@
 
 <!--#include file="status.gen" -->
 
-<h1>The current status of toybox (as of 0.4.1 release):</h1>
+<h1>The current status of toybox (as of 0.4.5 release):</h1>
 
 <h3><u>These commands are reasonably finished</u>:</h3>
 <blockquote><b>
 <span id=ready>
 basename cal cat catv chgrp chmod chown chvt cksum clear cmp comm count cp
-df dirname dmesg dos2unix echo env false gethostname groups killall link logname
-losetup ls lsmod md5sum mkdir mkfifo mkswap mktemp mv nice nohup od oneit
-pivot_root pwd readahead realpath rev rm seq setsid sha1sum sleep sort split
-stat swapoff swapon sync tac taskset tee time true truncate tty uniq unix2dos
+df dirname dmesg dos2unix echo egrep env false fgrep gethostname grep groups
+killall link logname losetup ls lsmod md5sum mkdir mkfifo mkswap mktemp mv
+nice nohup od oneit paste pivot_root pmap pwd readahead realpath renice rev
+rm seq setsid sha1sum sleep sort split stat swapoff swapon sync tac taskset
+tee time timeout true truncate tty uniq unix2dos
 unlink usleep uudecode uuencode wc which whoami yes
 </span>
 </b></blockquote>