From 08a453b5d5765ed73b69c147189978e144c8dfcc Mon Sep 17 00:00:00 2001 From: Belac Darkstorm Date: Tue, 13 Sep 2016 02:54:59 -0500 Subject: [PATCH] Proper executable detection (looks for #! or ELF at the beginning of the file) --- README.md | 12 ++++-------- main.go | 39 +++++++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index abfb569..ad2dbb5 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,6 @@ I'm trying to make it work well with [AppImages](http://appimage.org/). # Why? I know that Linux only has about 2% desktop usage and I know that the traditional way to install apps isn't portable, but over the past year or so I've started to put linux apps on my flash drive (AppImage is a great example of a portable solution to linux apps. Also a lot of DRM-free games can be run portably), but there was no easy way to organize my linux apps, so I created one. I personally have used the PortableApps.com launcher for years now and I love how properly formated the apps are, which allows me to grab info about the app easily. -# Why script files? -In general linux executable files have no extensions and can be a pain when trying to figure out what is executable and what isn't. I figured script files are easy to detect and allow a large amount of flexibility for me (and others who want to make apps work with this launcher). See below for .AppImage support (Get AppImages from [here](https://bintray.com/probono/AppImages)) - # Why Go? Because I like Go :) Also the way it includes all it needs into one friendly executable. @@ -20,15 +17,14 @@ The first place the program looks for an app's icon and info is in the /App/AppI # common.sh common.sh is run before any program so you can set environment variables (such as HOME). common.sh should be in PortableApps/LinuxPACom folder. Paths should be made relitive to where LinuxPA is. -# AppImage support -It will now launch .AppImage files! If a .sh script and an .AppImage executable are both in a directory, the .sh script takes precedence. You can get AppImages from [here](https://bintray.com/probono/AppImages). +# Executable search +For a given app, it tried to look for script files (looks for the file to start with `#!`) and then looks for standard executable files (looks for the file to start with `ELF`) # Screenshots -![LinuxPA](https://lh3.googleusercontent.com/hdMfnnqj7jgsIAxzOMq3RD6iBlP3EVpqmH7SgowgAbidm6TncmksHlScV4OUkw4aOwG_OKSR1ukHRSY0kEk3rLjh8BEI60ZZO6sZp45g2qSanlYcq4-moDlRnbZOtur88K6sSWZRKXfRZ9ItDahDAdQLz5By_nf_aA4NZjn0d2XS4pnfhIGOPXZ8iFKgNfKHzWicJLlLw0nfXuUSAf60btbNlRLF7N0LEPH0INb0HD-f9w1W99NVNT5ooE18fOLlVks-ySHtxI9bqhNqfMC4kVB1Zt843KPxQQ_Slb0D_KnW58f2ARtYZyttWvXWOF2QhFeSzy8vI_lMVpnbtThcov1TZDZpPhjkiEF4hMb75zez-wpJ5DaJNvUTUcbn7wrj55UN6GgoZK7N_zn8kVhwPhQEEomLyCO9dtO9x5R1rhKYdTukvrupodhZRzI4KE9akqaMHLk3FC8A54PDnQvzBBDcxODxjxbyPYF50K55n26zoq6DXeJqbLAiDqqkaoCO74OXHyUQJbycVaG2uXsYRQ-0HcAuvEWj9XdeqsKj9qwtQuOOTZpp5JTu-0uRnLjML5503fhTjJS8AkWyav7zguXKaMq-QpRiywWKEPSSB14RP4Xy=w500-h534-no) +Photos are found [Here](https://goo.gl/photos/VtBUL6DyZTMidj5n6) # TODO (Might be in order) -1. MAKE IT BETTER -1. Improve linux executable detection (A.K.A. a pain in the butt) (I'm currently thinking of checking each file to see if the file starts out with #! or ELF) +1. MAKE IT BETTER 1. Launching of .exe files via wine (wine will have to be installed on the host system, unless there is some portable wine, I may have found one) 1. Add settings menu 1. Add updater for .AppImage files diff --git a/main.go b/main.go index a0f74f1..e143416 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "bufio" "os" "path" + "reflect" "sort" "strings" @@ -79,18 +80,40 @@ func processApp(fi *os.File) (out prtap) { if out.cat == "" { out.cat = "other" } + //executable detection + wd, _ := os.Getwd() + var rdr *bufio.Reader for _, v := range fis { - if !v.IsDir() && strings.HasSuffix(strings.ToLower(v.Name()), ".sh") { - //do os check here for possible cross platform support - out.ex = fi.Name() + "/" + v.Name() - return + fil, err := os.Open(wd + "/" + fi.Name() + "/" + v.Name()) + if err == nil { + stat, _ := fil.Stat() + if !stat.IsDir() { + rdr = bufio.NewReader(fil) + shebang := []byte{'#', '!'} + two := make([]byte, 2) + rdr.Read(two) + if reflect.DeepEqual(shebang, two) { + out.ex = wd + "/" + fi.Name() + "/" + v.Name() + rdr.Reset(fil) + return + } + } } } for _, v := range fis { - if !v.IsDir() && strings.HasSuffix(strings.ToLower(v.Name()), ".appimage") { - //do os check here for possible cross platform support - out.ex = fi.Name() + "/" + v.Name() - return + fil, err := os.Open(wd + "/" + fi.Name() + "/" + v.Name()) + if err == nil { + stat, _ := fil.Stat() + if !stat.IsDir() { + rdr = bufio.NewReader(fil) + thr := make([]byte, 4) + rdr.Read(thr) + if strings.Contains(string(thr), "ELF") { + out.ex = wd + "/" + fi.Name() + "/" + v.Name() + rdr.Reset(fil) + return + } + } } } return prtap{}