eclair snapshot
diff --git a/toolbox/ls.c b/toolbox/ls.c
index f609df21..b221074 100644
--- a/toolbox/ls.c
+++ b/toolbox/ls.c
@@ -15,9 +15,11 @@
 #include <linux/kdev_t.h>
 
 // bits for flags argument
-#define LIST_LONG       (1 << 0)
-#define LIST_ALL        (1 << 1)
-#define LIST_RECURSIVE  (1 << 2)
+#define LIST_LONG           (1 << 0)
+#define LIST_ALL            (1 << 1)
+#define LIST_RECURSIVE      (1 << 2)
+#define LIST_DIRECTORIES    (1 << 3)
+#define LIST_SIZE           (1 << 4)
 
 // fwd
 static int listpath(const char *name, int flags);
@@ -84,7 +86,19 @@
     }
 }
 
-static int listfile(const char *path, int flags)
+static int listfile_size(const char *path, int flags)
+{
+    struct stat s;
+
+    if (lstat(path, &s) < 0)
+        return -1;
+
+    /* blocks are 512 bytes, we want output to be KB */
+    printf("%lld %s\n", s.st_blocks / 2, path);
+    return 0;
+}
+
+static int listfile_long(const char *path, int flags)
 {
     struct stat s;
     char date[32];
@@ -155,6 +169,30 @@
     return 0;
 }
 
+static int listfile(const char *dirname, const char *filename, int flags)
+{
+    if ((flags & (LIST_LONG | LIST_SIZE)) == 0) {
+        printf("%s\n", filename);
+        return 0;
+    }
+
+    char tmp[4096];
+    const char* pathname = filename;
+
+    if (dirname != NULL) {
+        snprintf(tmp, sizeof(tmp), "%s/%s", dirname, filename);
+        pathname = tmp;
+    } else {
+        pathname = filename;
+    }
+
+    if ((flags & LIST_LONG) != 0) {
+        return listfile_long(pathname, flags);
+    } else /*((flags & LIST_SIZE) != 0)*/ {
+        return listfile_size(pathname, flags);
+    }
+}
+
 static int listdir(const char *name, int flags)
 {
     char tmp[4096];
@@ -170,12 +208,8 @@
     while((de = readdir(d)) != 0){
         if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue;
         if(de->d_name[0] == '.' && (flags & LIST_ALL) == 0) continue;
-        if ((flags & LIST_LONG) != 0) {
-            sprintf(tmp, "%s/%s", name, de->d_name);
-            listfile(tmp, flags);
-        } else {
-            printf("%s\n", de->d_name);
-        }
+
+        listfile(name, de->d_name, flags);
     }
 
     if (flags & LIST_RECURSIVE) {
@@ -190,8 +224,10 @@
             if (de->d_name[0] == '.' && (flags & LIST_ALL) == 0)
                 continue;
 
-            if (!strcmp(name, "/")) sprintf(tmp, "/%s", de->d_name);
-            else sprintf(tmp, "%s/%s", name, de->d_name);
+            if (!strcmp(name, "/"))
+                snprintf(tmp, sizeof(tmp), "/%s", de->d_name);
+            else
+                snprintf(tmp, sizeof(tmp), "%s/%s", name, de->d_name);
 
             /*
              * If the name ends in a '/', use stat() so we treat it like a
@@ -238,18 +274,13 @@
         return -1;
     }
 
-    if (S_ISDIR(s.st_mode)) {
+    if ((flags & LIST_DIRECTORIES) == 0 && S_ISDIR(s.st_mode)) {
         if (flags & LIST_RECURSIVE)
             printf("\n%s:\n", name);
         return listdir(name, flags);
     } else {
-        if ((flags & LIST_LONG) != 0) {
-            /* yeah this calls stat() again*/
-            return listfile(name, flags);
-        } else {
-            printf("%s\n", name);
-            return 0;
-        }
+        /* yeah this calls stat() again*/
+        return listfile(NULL, name, flags);
     }
 }
 
@@ -263,12 +294,16 @@
         int err = 0;
 
         for (i = 1; i < argc; i++) {
-            if(!strcmp(argv[i], "-l")) {
+            if (!strcmp(argv[i], "-l")) {
                 flags |= LIST_LONG;
+            } else if (!strcmp(argv[i], "-s")) {
+                flags |= LIST_SIZE;
             } else if (!strcmp(argv[i], "-a")) {
                 flags |= LIST_ALL;
             } else if (!strcmp(argv[i], "-R")) {
                 flags |= LIST_RECURSIVE;
+            } else if (!strcmp(argv[i], "-d")) {
+                flags |= LIST_DIRECTORIES;
             } else {
                 listed++;
                 if(listpath(argv[i], flags) != 0) {