66import tempfile
77import os
88import magic
9+ import io
10+ from elftools .elf .elffile import ELFFile
911from PySquashfsImage import SquashFsImage
1012import gi
1113gi .require_version ("Gtk" , "3.0" )
@@ -43,20 +45,16 @@ def load_opk(path):
4345 desktopfile .read_string (i .getContent ().decode ("utf-8" ))
4446 dset = dict ()
4547 dset ['appname' ] = desktopfile ["Desktop Entry" ].get ("Name" , "" , raw = True )
46- dset ['executable' ] = os .path .basename (desktopfile ["Desktop Entry" ].get ("Exec" , "<none> " , raw = True ).split ()[0 ])
47- if dset ['executable' ] in execs :
48- execs [dset ['executable' ]]. add ( iname )
48+ dset ['executable' ] = os .path .basename (desktopfile ["Desktop Entry" ].get ("Exec" , "" , raw = True ).split ()[0 ])
49+ if dset ['executable' ] != "" :
50+ execs [dset ['executable' ]] = dict ( )
4951 else :
50- execs [dset ['executable' ]] = {iname }
51- dset ['execid' ] = ""
52+ dset ['executable' ] = "<none>"
5253 dset ['version' ] = desktopfile ["Desktop Entry" ].get ("Version" , "" , raw = True )
5354 dset ['comment' ] = desktopfile ["Desktop Entry" ].get ("Comment" , "" , raw = True )
5455 dset ['manualpath' ] = desktopfile ["Desktop Entry" ].get ("X-OD-Manual" , "" , raw = True )
55- if dset ['manualpath' ] in manuals :
56- manuals [dset ['manualpath' ]].add (iname )
57- else :
58- manuals [dset ['manualpath' ]] = {iname }
59- dset ['manual' ] = ""
56+ if dset ['manualpath' ] != "" :
57+ manuals [dset ['manualpath' ]] = ""
6058 desktops [iname ] = dset
6159 platformset .add (m .group (1 ))
6260 m = re .match (r".+\.png" , iname )
@@ -78,20 +76,24 @@ def load_opk(path):
7876 man = ""
7977 for e in encodings :
8078 try :
81- man = i .getContent ().decode (e )
79+ manuals [ iname ] = i .getContent ().decode (e )
8280 break
8381 except :
84- man = "<reading error>"
85- for m in manuals [iname ]:
86- desktops [m ]['manual' ] = man
82+ manuals [iname ] = "<reading error>"
8783 if iname in execs :
88- ei = magic .from_buffer (i .getContent ())
89- for e in execs [iname ]:
90- desktops [e ]['execid' ] = ei
91- # workaround for libmagic from_file vs from_buffer bug for elves
92- #with tempfile.NamedTemporaryFile() as f:
93- # f.write(i.getContent())
94- # execid = magic.from_file(f.name)
84+ execs [iname ]['magic' ] = magic .from_buffer (i .getContent ())
85+ execs [iname ]['mime' ] = magic .from_buffer (i .getContent (), mime = True )
86+ execs [iname ]['iself' ] = execs [iname ]['mime' ] == 'application/x-executable' or execs [iname ]['mime' ] == 'application/x-pie-executable'
87+ if execs [iname ]['iself' ]:
88+ bstream = io .BytesIO (i .getContent ())
89+ elf = ELFFile (bstream )
90+ dynsec = elf .get_section_by_name (".dynamic" )
91+ execs [iname ]['dynamic' ] = dynsec is not None
92+ if execs [iname ]['dynamic' ]:
93+ execs [iname ]['deps' ] = []
94+ for tag in dynsec .iter_tags ():
95+ if tag .entry .d_tag == "DT_NEEDED" :
96+ execs [iname ]['deps' ].append (tag .needed )
9597 opk .close ()
9698 if platforms == "" :
9799 platforms = "none"
@@ -104,14 +106,37 @@ def load_opk(path):
104106 desktops [key ]['appname' ] = "none"
105107 content += "Appname: " + desktops [key ]['appname' ] + "\n "
106108 content += "Executable: " + desktops [key ]['executable' ] + "\n "
107- content += "Exec identity: " + desktops [key ]['execid' ] + "\n "
108109 if desktops [key ]['version' ] != "" :
109110 content += "Version: " + desktops [key ]['version' ] + "\n "
110111 if desktops [key ]['comment' ] != "" :
111112 content += "Comment: " + desktops [key ]['comment' ] + "\n "
112- if desktops [key ]['manual' ] != "" :
113- content += "Manual:\n " + desktops [key ]['manual' ] + "\n "
113+ if desktops [key ]['manualpath' ] != "" :
114+ content += "Manual: " + desktops [key ]['manualpath' ] + "\n "
115+ content += "\n "
116+ for key in execs :
117+ content += "Executable " + key + "\n "
118+ content += "Identity: " + execs [key ]['magic' ] + "\n "
119+ if execs [key ]['iself' ]:
120+ if execs [key ]['dynamic' ]:
121+ content += "The executable is dynamically linked.\n "
122+ if len (execs [key ]['deps' ]) == 0 :
123+ content += "No dynamic dependencies detected.\n "
124+ else :
125+ content += "Dynamic dependencies:\n "
126+ for d in execs [key ]['deps' ]:
127+ content += " " + d + "\n "
128+ else :
129+ content += "The executable is statically linked.\n "
114130 content += "\n "
131+ for key in manuals :
132+ if manuals [key ] == "" :
133+ content += "Manual " + key + " is empty or nonexistent.\n "
134+ else :
135+ content += "Manual " + key + "\n "
136+ content += "=== MANUAL START ===\n "
137+ content += manuals [key ] + "\n "
138+ content += "=== MANUAL END ===\n "
139+ content += "\n "
115140 textbuffer .set_text (content )
116141
117142class Handler :
@@ -129,6 +154,9 @@ def onOpen(self, *args):
129154 load_opk (filepath )
130155 dialog .destroy ()
131156
157+ def onExtract (self , * args ):
158+ print ("Extract clicked" )
159+
132160 def onAbout (self , * args ):
133161 aboutdialog .show ()
134162
0 commit comments