--- /dev/null
+#!/usr/bin/env python
+#
+# update-config.py: A program to help automate updating the
+# kernel configuration.
+#
+# Copyright (C) 2018 Jason Self <j@jxself.org>
+#
+# You will need Python and pexpect.
+#
+# A file named base_config containing config options (without the
+# leading CONFIG_) needs to live in the root level of the kernel
+# source tree. This program will run make oldconfig, responding to
+# prompts for config options using the information in that
+# base_config file. If no match is found it will pause so that you
+# can answer, unless USE_DEFAULT is to true. In that case the program
+# will accept whatever the default answer is and continue on.
+#
+# SPDX-License-Identifier: AGPL-3.0-or-later
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Affero General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public
+# License along with this program. If not, see
+# <https://www.gnu.org/licenses/>.
+
+import subprocess
+import sys
+import pexpect
+import select
+
+TIMEOUT = 1
+USE_DEFAULT = False
+TRACE = False
+CHOICE_PROMPT = False
+
+configs = {}
+
+def readBaseConfig(baseConfigFile):
+ f = open(baseConfigFile)
+ for l in f.readlines():
+ if len(l) < 3 or l.strip()[0] == '#':
+ continue
+ if l.find('=') != -1:
+ optVal = l.split('=')
+ key = '(' + optVal[0].strip().replace('CONFIG_', '') + ')'
+ val = optVal[1].strip().replace('"', '')
+ configs[key] = val
+
+def mainSelect():
+ cmd = 'make oldconfig'
+ proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+ fLog = open('kernelexpect.log', 'w+')
+ print("Starting")
+ validConfig = False
+ b = ''
+ l = ''
+ timeLimit = TIMEOUT
+ while True:
+ pollResult = select.select([proc.stdout], [], [], timeLimit)[0]
+ if len(pollResult) != 0:
+ c = proc.stdout.read(1)
+ if c == '':
+ break
+ b += c
+ l += c
+ if c == '\r' or c == '\n':
+ l = ''
+ sys.stdout.write(c)
+ sys.stdout.flush()
+ fLog.write(c)
+ fLog.flush()
+ else:
+ print '\n**** Timeout ***'
+ if not validConfig:
+ if b.find('Restart config') != -1:
+ validConfig = True
+ else:
+ print 'Waiting for valid config'
+ continue
+
+ found = False
+ l = l.strip()
+ for k in configs:
+ if l.find(k + ' [') != -1:
+ print 'Found key', k, 'in line', 'setting value', configs[k]
+ proc.stdin.write(configs[k] + '\n')
+ found = True
+
+ if l.startswith('choice'):
+ if CHOICE_PROMPT:
+ print 'Please enter your option'
+ v = sys.stdin.readline()
+ print 'Setting value', v
+ proc.stdin.write(v)
+ found = True
+ else:
+ options = int(l.replace('choice[1-', '').replace('?', '').replace(']', '').replace(':', ''))
+ print 'Options', options
+ ls = b.split('\n')[-options-1:-1]
+ l1 = ls[0]
+ print 'List', ls
+ print 'First', l1
+ for lc in ls:
+ for k in configs:
+ if configs[k] != 'y':
+ continue
+ if lc.find(k) != -1:
+ print 'Found key', k, 'in line', 'setting value', configs[k]
+ lc = lc.replace('>', '').strip()
+ pos = lc.find('.')
+ option = lc[:pos]
+ print 'Using option', option
+ proc.stdin.write(option + '\n')
+ found = True
+
+ if not found:
+ if not USE_DEFAULT:
+ print 'Please enter your option'
+ v = sys.stdin.readline()
+ print 'Setting value', v
+ proc.stdin.write(v)
+ found = True
+ else:
+ print 'Using default'
+ proc.stdin.write('\n')
+
+ print '****************'
+ b = ''
+ l = ''
+
+readBaseConfig('base_config')
+
+if TRACE:
+ for k in configs.keys():
+ print k, configs[k]
+
+mainSelect()