Several improvements

* Flush stdin before reading.
 * Decode Base64 content.
 * Use email module to parse patches.
 * Remove empty unused function process_vuln().
 * Fix caf detection.
 * Detect bcmdhd, mtk.
 * Show patch subject and version.
This commit is contained in:
Tom Marshall 2017-08-21 20:14:24 +00:00
parent ca32c4da80
commit 64f59e2f25
1 changed files with 42 additions and 25 deletions

View File

@ -3,8 +3,10 @@
import os import os
import sys import sys
import requests import requests
import base64
import getopt import getopt
from xml.etree import ElementTree from xml.etree import ElementTree
import email
import subprocess import subprocess
cfg = dict() cfg = dict()
@ -26,6 +28,17 @@ def cmd_run(args, stdin=None):
rc = child.returncode rc = child.returncode
return (rc, out.rstrip('\n').split('\n'), err.rstrip('\n').split('\n')) return (rc, out.rstrip('\n').split('\n'), err.rstrip('\n').split('\n'))
def get_input(s):
# https://rosettacode.org/wiki/Keyboard_input/Flush_the_keyboard_buffer#Python
try:
import msvcrt
while msvcrt.kbhit():
msvcrt.getch()
except ImportError:
import termios #for linux/unix
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
return raw_input(s)
class Version: class Version:
def __init__(self, ver): def __init__(self, ver):
self._segments = [] self._segments = []
@ -92,20 +105,24 @@ class Patch:
rs = requests.Session() rs = requests.Session()
r = rs.get(self._url) r = rs.get(self._url)
r.raise_for_status() r.raise_for_status()
self._text = r.content if r.content.startswith('From '):
for line in self._text.rstrip('\n').split('\n'): self._text = r.content
fields = line.split(' ', 1) else:
if len(fields) < 2: self._text = base64.b64decode(r.content)
continue
if fields[0] == 'From': message = email.message_from_string(self._text)
self._sha = fields[1] s = message.get_unixfrom()
if fields[0] == 'From:': if not s:
self._author = fields[1] return
if fields[0] == 'Date:': self._sha = s.split(' ', 2)[1]
self._date = fields[1] self._author = message['From']
if fields[0] == 'Subject:': self._date = message['Date']
self._subject = fields[1].strip() self._subject = message['Subject']
if fields[0] == 'diff': self._subject = self._subject.replace('\n', '')
s = message.get_payload(decode=True)
for line in s.rstrip('\n').split('\n'):
if line.startswith('diff '):
fields = line.split(' ') fields = line.split(' ')
self._files.append(fields[2][2:]) self._files.append(fields[2][2:])
@ -271,20 +288,20 @@ class Vuln:
return return
sys.stdout.write(" Failed, patching manually ...\n") sys.stdout.write(" Failed, patching manually ...\n")
patch.apply() patch.apply()
reply = raw_input(" Please verify and press enter to continue...") reply = get_input(" Please verify and press enter to continue...")
argv = ['git', 'add'] argv = ['git', 'add']
argv.extend(patch.files()) argv.extend(patch.files())
(rc, out, err) = cmd_run(argv) (rc, out, err) = cmd_run(argv)
if rc != 0: if rc != 0:
# Should never happen # Should never happen
print " *** Failed to add git files" print " *** Failed to add git files"
reply = raw_input(" Please add/remove files and press enter: ") reply = get_input(" Please add/remove files and press enter: ")
argv = ['git', 'am', '--continue'] argv = ['git', 'am', '--continue']
(rc, out, err) = cmd_run(argv) (rc, out, err) = cmd_run(argv)
if rc != 0: if rc != 0:
# Should never happen # Should never happen
print " *** Failed to continue merge" print " *** Failed to continue merge"
reply = raw_input(" Please complete merge and press enter: ") reply = get_input(" Please complete merge and press enter: ")
sys.stdout.write(" ") sys.stdout.write(" ")
self.applied(True) self.applied(True)
self.action('Applied manually') self.action('Applied manually')
@ -347,10 +364,6 @@ def get_vuln_list():
sys.stdout.flush() sys.stdout.flush()
return sorted(vuln_list, key = lambda x:x._key) return sorted(vuln_list, key = lambda x:x._key)
# Process a vuln and update status.
def process_vuln(vuln, ver):
return
### Begin main code ### ### Begin main code ###
if not sys.stdin.isatty(): if not sys.stdin.isatty():
@ -371,13 +384,16 @@ ksources = set()
ksources.add('mainline') ksources.add('mainline')
if os.path.exists('drivers/staging/android'): if os.path.exists('drivers/staging/android'):
ksources.add('android') ksources.add('android')
if os.path.exists('arch/arm/mach-msm'): if os.path.exists('drivers/misc/qcom'):
ksources.add('caf') ksources.add('caf')
# XXX: mtk? if os.path.exists('drivers/misk/mediatek'):
ksources.add('mtk')
if os.path.exists('drivers/staging/prima'): if os.path.exists('drivers/staging/prima'):
ksources.add('prima') ksources.add('prima')
if os.path.exists('drivers/staging/qcacld-2.0'): if os.path.exists('drivers/staging/qcacld-2.0'):
ksources.add('qcacld') ksources.add('qcacld')
if os.path.exists('drivers/net/wireless/bcmdhd'):
ksources.add('bcmdhd')
# ... # ...
get_git_history() get_git_history()
@ -438,12 +454,13 @@ for vuln in vuln_list:
else: else:
sys.stdout.write(" ... Paches:\n") sys.stdout.write(" ... Paches:\n")
for k in patches: for k in patches:
sys.stdout.write(" %s: %s\n" % (k, patches[k].url())) sys.stdout.write(" %s: %s\n" % (k, patches[k].subject()))
sys.stdout.write(" %s\n" % (patches[k].url()))
reply = '' reply = ''
if cfg['ni']: if cfg['ni']:
reply = 's' reply = 's'
while reply != 'a' and reply != 's': while reply != 'a' and reply != 's':
reply = raw_input(" Please apply manually. [S]kip or [A]pplied: ") reply = get_input(" Please apply manually. [S]kip or [A]pplied: ")
if len(reply) > 0: if len(reply) > 0:
reply = reply[0].lower() reply = reply[0].lower()
else: else: