Repository: androguard/androguard
Issue: --silent option not working properly causes errno 36 file name too long on terminal

I wanted to do decompile an apk file

- is this error specific to a single file?
apparently it will happen whenever a file's name is too long OR it is nested deep

- if possible give a minimal working example where the error happens

setting --silent option like: 
androguard --silent decompile app.apk --output ./outputdir

### Describe what you expected

not expected to ocurr when --silent is set

### Describe what actually happened
Androguard runs silently but starts echoing logs after a while

### System Information

- Androguard Version: 
`androguard --version`
> androguard, version 3.3.5

- Python Version: 2.7 (from error log below)
- Operating System
`uname -r`

> 4.19.0-kali5-amd64

`uname -a`

> Linux device_name 4.19.0-kali5-amd64 #1 SMP Debian 4.19.37-6kali1 (2019-07-22) x86_64 GNU/Linux

`cat /proc/version`

> Linux version 4.19.0-kali5-amd64 (devel@kali.org) (gcc version 8.3.0 (Debian 8.3.0-6)) #1 SMP Debian 4.19.37-6kali1 (2019-07-22)


###Output

everything runs smooth and goes on dumping until the error appears as:

>  File "/usr/local/bin/androguard", line 10, in <module>
>     sys.exit(entry_point())
>   File "/usr/lib/**python2.7**/dist-packages/click/core.py", line 764, in __call__
>     return self.main(*args, **kwargs)
>   File "/usr/lib/python2.7/dist-packages/click/core.py", line 717, in main
>     rv = self.invoke(ctx)
>   File "/usr/lib/python2.7/dist-packages/click/core.py", line 1137, in invoke
>     return _process_result(sub_ctx.command.invoke(sub_ctx))
>   File "/usr/lib/python2.7/dist-packages/click/core.py", line 956, in invoke
>     return ctx.invoke(self.callback, **ctx.params)
>   File "/usr/lib/python2.7/dist-packages/click/core.py", line 555, in invoke
>     return callback(*args, **kwargs)
>   File "/usr/local/lib/python2.7/dist-packages/androguard/cli/entry_points.py", line 395, in decompile
>     jar, decompiler, format_)
>   File "/usr/local/lib/_python2.7_/dist-packages/androguard/cli/main.py", line 275, in export_apps_to_format
>     with open(filename + ".ag", "w") as fd:
> IOError: [Errno 36] File name too long: u'**./outputdir/nine/subdirs/deep/** buildFeedbackEvent (String String String D D String String I I I Date String [Location [Location I I I String String String String Z String String String I I String String String String String String String String String I I I I I I)Hashtable.ag'


Changed files:
tests/test_misc.py, androguard/misc.py

diff --git a/androguard/misc.py b/androguard/misc.py
index 67b36f61..9e3bd37c 100644
--- a/androguard/misc.py
+++ b/androguard/misc.py
@@ -209,16 +209,22 @@ def clean_file_name(filename, unique=True, replace="_", force_nt=False):
     # Do not end with dot or space
     fname = re.sub(r'[ .]$', replace, fname)
 
-    if force_nt or os.name == 'nt':
-        PATH_MAX_LENGTH = 230  # give extra space for other stuff...
-        # Check filename length limit, usually a problem on older Windows versions
-        if len(fname) > PATH_MAX_LENGTH:
-            if "." in fname:
-                f, ext = fname.rsplit(".", 1)
-                fname = "{}.{}".format(f[:PATH_MAX_LENGTH-(len(ext)+1)], ext)
-            else:
-                fname = fname[:PATH_MAX_LENGTH]
+    # It is a sensible default, to assume that there is a hard 255 char limit per filename
+    # See https://en.wikipedia.org/wiki/Comparison_of_file_systems
+    # If you are using a filesystem with less, you have other problems ;)
+    #
+    # We simply make a hard cut after 255 chars. To leave some space for an extension, which might get added later,
+    # There is room for improvement here, so feel free to implement a better method!
+    PATH_MAX_LENGTH = 230  # give extra space for other stuff...
+    # Check filename length limit, usually a problem on older Windows versions
+    if len(fname) > PATH_MAX_LENGTH:
+        if "." in fname:
+            f, ext = fname.rsplit(".", 1)
+            fname = "{}.{}".format(f[:PATH_MAX_LENGTH-(len(ext)+1)], ext)
+        else:
+            fname = fname[:PATH_MAX_LENGTH]
 
+    if force_nt or os.name == 'nt':
         # Special behaviour... On Windows, there is also a problem with the maximum path length in explorer.exe
         # maximum length is limited to 260 chars, so use 250 to have room for other stuff
         if len(os.path.abspath(os.path.join(path, fname))) > 250:
diff --git a/tests/test_misc.py b/tests/test_misc.py
index df67f335..32ed6ee4 100644
--- a/tests/test_misc.py
+++ b/tests/test_misc.py
@@ -11,11 +11,11 @@ class MiscTest(unittest.TestCase):
         self.assertEqual("foobarsdf_", clean_file_name("foobarsdf.", unique=False))
         self.assertEqual("_init_", clean_file_name("<init>", unique=False))
         if os.name == "nt":
-            self.assertEqual("C:\\\\" + "a" * 230, clean_file_name("C:\\\\" + "a" * 999, unique=False, force_nt=True))
-            self.assertEqual("C:\\\\" + "a" * 226 + ".foo", clean_file_name("C:\\\\" + "a" * 999 + ".foo", unique=False, force_nt=True))
+            self.assertEqual("C:\\\\" + "a" * 230, clean_file_name("C:\\\\" + "a" * 999, unique=False))
+            self.assertEqual("C:\\\\" + "a" * 226 + ".foo", clean_file_name("C:\\\\" + "a" * 999 + ".foo", unique=False))
         else:
-            self.assertEqual("/some/path/" + "a" * 230, clean_file_name("/some/path/" + "a" * 999, unique=False, force_nt=True))
-            self.assertEqual("/some/path/" + "a" * 226 + ".foo", clean_file_name("/some/path/" + "a" * 999 + ".foo", unique=False, force_nt=True))
+            self.assertEqual("/some/path/" + "a" * 230, clean_file_name("/some/path/" + "a" * 999, unique=False))
+            self.assertEqual("/some/path/" + "a" * 226 + ".foo", clean_file_name("/some/path/" + "a" * 999 + ".foo", unique=False))
 
         with tempfile.NamedTemporaryFile() as fp:
             self.assertEqual(fp.name + "_0", clean_file_name(fp.name, unique=True))