atj: provide default output prefix/filenames on unpacking

If no output prefix is specified, a default is picked:
- filename with extension replaced by .afi for FWU files
- filename with extension replaced by .fw/ for AFI files
- filename without extension and with / for FW files

Change-Id: I6497b8f4a49f1238e5db738429f687cad3ae8a5a
diff --git a/utils/atj2137/atjboottool/atjboottool.c b/utils/atj2137/atjboottool/atjboottool.c
index 3fb9874..bbc2226 100644
--- a/utils/atj2137/atjboottool/atjboottool.c
+++ b/utils/atj2137/atjboottool/atjboottool.c
@@ -8,6 +8,7 @@
 #include <ctype.h>
 #include "misc.h"
 #include "elf.h"
+#include <sys/stat.h>
 
 #ifndef MIN
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -19,6 +20,7 @@
 
 bool g_debug = false;
 char *g_out_prefix = NULL;
+char *g_in_file = NULL;
 bool g_force = false;
 
 #define let_the_force_flow(x) do { if(!g_force) return x; } while(0)
@@ -872,6 +874,37 @@
     return 0;
 }
 
+/* [add]: string to add when there is no extension
+ * [replace]: string to replace extension */
+static void build_out_prefix(char *add, char *replace, bool slash)
+{
+    if(g_out_prefix)
+        return;
+    /** copy input filename with extra space */
+    g_out_prefix = malloc(strlen(g_in_file) + strlen(add) + 16);
+    strcpy(g_out_prefix, g_in_file);
+    /** remove extension and add '/' */
+    char *filename = strrchr(g_out_prefix, '/');
+    // have p points to the beginning or after the last '/'
+    filename = (filename == NULL) ? g_out_prefix : filename + 1;
+    // extension ?
+    char *dot = strrchr(filename, '.');
+    if(dot)
+    {
+        *dot = 0; // cut at the dot
+        strcat(dot, replace);
+    }
+    else
+        strcat(filename, add); // add extra string
+
+    if(slash)
+    {
+        strcat(filename, "/");
+        /** make sure the directory exists */
+        mkdir(g_out_prefix, S_IRWXU | S_IRGRP | S_IROTH);
+    }
+}
+
 static int do_fwu(uint8_t *buf, int size)
 {
     struct fwu_hdr_t *hdr = (void *)buf;
@@ -931,6 +964,8 @@
         let_the_force_flow(__LINE__);
     }
 
+    build_out_prefix(".afi", ".afi", false);
+
     if(g_version[ver].version == 3)
     {
         uint8_t unk[32];
@@ -940,15 +975,16 @@
         int ret = do_sthg_fwu_v3(buf, &size, unk, block);
         continue_the_force(ret);
 
-        if(g_out_prefix)
+        cprintf(GREY, "Descrambling to %s... ", g_out_prefix);
+        FILE *f = fopen(g_out_prefix, "wb");
+        if(f)
         {
-            FILE *f = fopen(g_out_prefix, "wb");
-            if(f)
-            {
-                fwrite(buf, size, 1, f);
-                fclose(f);
-            }
+            fwrite(buf, size, 1, f);
+            fclose(f);
+            cprintf(RED, "Ok\n");
         }
+        else
+            cprintf(RED, "Failed: %m\n");
     }
     
     return 0;
@@ -1096,6 +1132,8 @@
     cprintf_field("  Reserved: ", "%x %x %x\n", afi->hdr.res[0],
         afi->hdr.res[1], afi->hdr.res[2]);
 
+    build_out_prefix(".fw", "", true);
+    
     cprintf(BLUE, "Entries\n");
     for(int i = 0; i < AFI_ENTRIES; i++)
     {
@@ -1117,17 +1155,19 @@
         uint32_t chk = afi_checksum(buf + entry->offset, entry->size);
         cprintf(RED, "%s\n", chk == entry->checksum ? "Ok" : "Mismatch");
 
-        if(g_out_prefix)
+        char *name = malloc(strlen(g_out_prefix) + strlen(filename) + 16);
+        sprintf(name, "%s%s", g_out_prefix, filename);
+        
+        cprintf(GREY, "Unpacking to %s... ", name);
+        FILE *f = fopen(name, "wb");
+        if(f)
         {
-            char *name = malloc(strlen(g_out_prefix) + strlen(filename) + 16);
-            sprintf(name, "%s%s", g_out_prefix, filename);
-            FILE *f = fopen(name, "wb");
-            if(f)
-            {
-                fwrite(buf + entry->offset, entry->size, 1, f);
-                fclose(f);
-            }
+            fwrite(buf + entry->offset, entry->size, 1, f);
+            fclose(f);
+            cprintf(RED, "Ok\n");
         }
+        else
+            cprintf(RED, "Failed: %m\n");
     }
 
     cprintf(BLUE, "Post Header\n");
@@ -1260,6 +1300,8 @@
     cprintf_field("  MTP PID: ", "0x%x\n", hdr->mtp_pid);
     cprintf_field("  FW Version: ", "%.64s\n", hdr->fw_ver);
 
+    build_out_prefix(".unpack", "", true);
+    
     cprintf(BLUE, "Entries\n");
     for(int i = 0; i < AFI_ENTRIES; i++)
     {
@@ -1280,12 +1322,17 @@
         {
             char *name = malloc(strlen(g_out_prefix) + strlen(filename) + 16);
             sprintf(name, "%s%s", g_out_prefix, filename);
+            
+            cprintf(GREY, "Unpacking to %s... ", name);
             FILE *f = fopen(name, "wb");
             if(f)
             {
                 fwrite(buf + (entry->block_offset << 9), entry->size, 1, f);
                 fclose(f);
+                cprintf(RED, "Ok\n");
             }
+            else
+            cprintf(RED, "Failed: %m\n");
         }
     }
 
@@ -1315,6 +1362,7 @@
     printf("  --fw\tUnpack a FW archive file\n");
     printf("The default is to try to guess the format.\n");
     printf("If several formats are specified, all are tried.\n");
+    printf("If no output prefix is specified, a default one is picked.\n");
     exit(1);
 }
 
@@ -1380,7 +1428,8 @@
         return 1;
     }
 
-    FILE *fin = fopen(argv[optind], "r");
+    g_in_file = argv[optind];
+    FILE *fin = fopen(g_in_file, "r");
     if(fin == NULL)
     {
         perror("Cannot open boot file");