Add a new 'Show log' extended function.
Could also be used to report last lines from log on error.

Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>

Change-Id: I3d9e51f4e81e48f20120e2449ccde651efae8d07
diff --git a/common.h b/common.h
index 77cf143..b83055e 100644
--- a/common.h
+++ b/common.h
@@ -33,6 +33,7 @@
 // The screen is small, and users may need to report these messages to support,
 // so keep the output short and not too cryptic.
 void ui_print(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
+void ui_printlogtail(int nb_lines);
 
 void ui_reset_text_col();
 void ui_set_show_text(int value);
diff --git a/extendedcommands.c b/extendedcommands.c
index c2a0e18..ae41f06 100644
--- a/extendedcommands.c
+++ b/extendedcommands.c
@@ -876,6 +876,7 @@
                             "Wipe Battery Stats",
                             "Report Error",
                             "Key Test",
+                            "Show log",
 #ifndef BOARD_HAS_SMALL_RECOVERY
                             "Partition SD Card",
                             "Fix Permissions",
@@ -894,8 +895,10 @@
         switch (chosen_item)
         {
             case 0:
+            {
                 reboot_wrapper("recovery");
                 break;
+            }
             case 1:
             {
                 if (0 != ensure_path_mounted("/data"))
@@ -937,6 +940,11 @@
             }
             case 5:
             {
+                ui_printlogtail(12);
+                break;
+            }
+            case 6:
+            {
                 static char* ext_sizes[] = { "128M",
                                              "256M",
                                              "512M",
@@ -978,7 +986,7 @@
                     ui_print("An error occured while partitioning your SD Card. Please see /tmp/recovery.log for more details.\n");
                 break;
             }
-            case 6:
+            case 7:
             {
                 ensure_path_mounted("/system");
                 ensure_path_mounted("/data");
@@ -987,7 +995,7 @@
                 ui_print("Done!\n");
                 break;
             }
-            case 7:
+            case 8:
             {
                 static char* ext_sizes[] = { "128M",
                                              "256M",
diff --git a/ui.c b/ui.c
index 133f4da..d953562 100644
--- a/ui.c
+++ b/ui.c
@@ -29,6 +29,8 @@
 #include "minui/minui.h"
 #include "recovery_ui.h"
 
+extern int __system(const char *command);
+
 #ifdef BOARD_HAS_NO_SELECT_BUTTON
 static int gShowBackButton = 1;
 #else
@@ -58,6 +60,7 @@
 static gr_surface gProgressBarEmpty;
 static gr_surface gProgressBarFill;
 static int ui_has_initialized = 0;
+static int ui_log_stdout = 1;
 
 static const struct { gr_surface* surface; const char *name; } BITMAPS[] = {
     { &gBackgroundIcon[BACKGROUND_ICON_INSTALLING], "icon_installing" },
@@ -98,7 +101,7 @@
 static char menu[MENU_MAX_ROWS][MENU_MAX_COLS];
 static int show_menu = 0;
 static int menu_top = 0, menu_items = 0, menu_sel = 0;
-static int menu_show_start = 0;             // this is line which menu display is starting at 
+static int menu_show_start = 0;             // this is line which menu display is starting at
 
 // Key event input queue
 static pthread_mutex_t key_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -460,7 +463,8 @@
     vsnprintf(buf, 256, fmt, ap);
     va_end(ap);
 
-    fputs(buf, stdout);
+    if (ui_log_stdout)
+        fputs(buf, stdout);
 
     // This can get called before ui_init(), so be careful.
     pthread_mutex_lock(&gUpdateMutex);
@@ -481,6 +485,28 @@
     pthread_mutex_unlock(&gUpdateMutex);
 }
 
+void ui_printlogtail(int nb_lines) {
+    char * log_data;
+    char tmp[PATH_MAX];
+    FILE * f;
+    int line=0;
+    //don't log output to recovery.log
+    ui_log_stdout=0;
+    sprintf(tmp, "tail -n %d /tmp/recovery.log > /tmp/tail.log", nb_lines);
+    __system(tmp);
+    f = fopen("/tmp/tail.log", "rb");
+    if (f != NULL) {
+        while (line < nb_lines) {
+            log_data = fgets(tmp, PATH_MAX, f);
+            if (log_data == NULL) break;
+            ui_print("%s", tmp);
+            line++;
+        }
+        fclose(f);
+    }
+    ui_log_stdout=1;
+}
+
 void ui_reset_text_col()
 {
     pthread_mutex_lock(&gUpdateMutex);