1#!/usr/bin/python 2# 3# (C) International Business Machines 2008 4# Author: Andy Whitcroft 5# 6# Inspired by kernelexpand by: 7# (C) Martin J. Bligh 2003 8# 9# Released under the GPL, version 2 10 11import sys, re, os 12 13kernel = 'http://www.kernel.org/pub/linux/kernel/' 14mappings = [ 15 [ r'^\d+\.\d+\.\d+$', '', True, [ 16 kernel + 'v%(major)s/linux-%(full)s.tar.bz2' 17 ]], 18 [ r'^\d+\.\d+\.\d+\.\d+$', '', True, [ 19 kernel + 'v%(major)s/linux-%(full)s.tar.bz2' 20 ]], 21 [ r'-rc\d+$', '%(minor-prev)s', True, [ 22 kernel + 'v%(major)s/testing/v%(minor)s/linux-%(full)s.tar.bz2', 23 kernel + 'v%(major)s/testing/linux-%(full)s.tar.bz2', 24 ]], 25 [ r'-(git|bk)\d+$', '%(base)s', False, [ 26 kernel + 'v%(major)s/snapshots/old/patch-%(full)s.bz2', 27 kernel + 'v%(major)s/snapshots/patch-%(full)s.bz2', 28 ]], 29 [ r'-mm\d+$', '%(base)s', False, [ 30 kernel + 'people/akpm/patches/' + 31 '%(major)s/%(base)s/%(full)s/%(full)s.bz2' 32 ]], 33 [ r'-mjb\d+$', '%(base)s', False, [ 34 kernel + 'people/mbligh/%(base)s/patch-%(full)s.bz2' 35 ]] 36]; 37 38def decompose_kernel_once(kernel): 39 ##print "S<" + kernel + ">" 40 for mapping in mappings: 41 (suffix, becomes, is_full, patch_templates) = mapping 42 43 params = {} 44 45 match = re.search(r'^(.*)' + suffix, kernel) 46 if not match: 47 continue 48 49 # Generate the parameters for the patches: 50 # full => full kernel name 51 # base => all but the matches suffix 52 # minor => 2.n.m 53 # major => 2.n 54 # minor-prev => 2.n.m-1 55 params['full'] = kernel 56 params['base'] = match.group(1) 57 58 match = re.search(r'^((\d+\.\d+)\.(\d+))', kernel) 59 if not match: 60 raise "unable to determine major/minor version" 61 params['minor'] = match.group(1) 62 params['major'] = match.group(2) 63 params['minor-prev'] = match.group(2) + '.%d' % (int(match.group(3)) -1) 64 65 # Build the new kernel and patch list. 66 new_kernel = becomes % params 67 patch_list = [] 68 for template in patch_templates: 69 patch_list.append(template % params) 70 71 return (is_full, new_kernel, patch_list) 72 73 return (True, kernel, None) 74 75 76def decompose_kernel(kernel): 77 kernel_patches = [] 78 79 done = False 80 while not done: 81 (done, kernel, patch_list) = decompose_kernel_once(kernel) 82 if patch_list: 83 kernel_patches.insert(0, patch_list) 84 if not len(kernel_patches): 85 raise NameError('kernelexpand: %s: unknown kernel' % (kernel)) 86 87 return kernel_patches 88 89 90# Look for and add potential mirrors. 91def mirror_kernel_components(mirrors, components): 92 new_components = [] 93 for component in components: 94 new_patches = [] 95 for mirror in mirrors: 96 (prefix, local) = mirror 97 for patch in component: 98 if patch.startswith(prefix): 99 new_patch = local + patch[len(prefix):] 100 new_patches.append(new_patch) 101 for patch in component: 102 new_patches.append(patch) 103 new_components.append(new_patches) 104 105 return new_components 106 107 108def url_accessible(url): 109 status = os.system("wget --spider -q '%s'" % (url)) 110 #print url + ": status=%d" % (status) 111 112 return status == 0 113 114 115def select_kernel_components(components): 116 new_components = [] 117 for component in components: 118 new_patches = [] 119 for patch in component: 120 if url_accessible(patch): 121 new_patches.append(patch) 122 break 123 if not len(new_patches): 124 new_patches.append(component[-1]) 125 new_components.append(new_patches) 126 return new_components 127 128 129def expand_classic(kernel, mirrors): 130 components = decompose_kernel(kernel) 131 if mirrors: 132 components = mirror_kernel_components(mirrors, components) 133 components = select_kernel_components(components) 134 135 patches = [] 136 for component in components: 137 patches.append(component[0]) 138 139 return patches 140 141 142if __name__ == '__main__': 143 from optparse import OptionParser 144 145 parser = OptionParser() 146 147 parser.add_option("-m", "--mirror", type="string", dest="mirror", 148 action="append", nargs=2, help="mirror prefix") 149 parser.add_option("-v", "--no-validate", dest="validate", 150 action="store_false", default=True, help="prune invalid entries") 151 152 def usage(): 153 parser.print_help() 154 sys.exit(1) 155 156 options, args = parser.parse_args() 157 158 # Check for a kernel version 159 if len(args) != 1: 160 usage() 161 kernel = args[0] 162 163 #mirrors = [ 164 # [ 'http://www.kernel.org/pub/linux/kernel/v2.4', 165 # 'http://kernel.beaverton.ibm.com/mirror/v2.4' ], 166 # [ 'http://www.kernel.org/pub/linux/kernel/v2.6', 167 # 'http://kernel.beaverton.ibm.com/mirror/v2.6' ], 168 # [ 'http://www.kernel.org/pub/linux/kernel/people/akpm/patches', 169 # 'http://kernel.beaverton.ibm.com/mirror/akpm' ], 170 #] 171 mirrors = options.mirror 172 173 try: 174 components = decompose_kernel(kernel) 175 except NameError, e: 176 sys.stderr.write(e.args[0] + "\n") 177 sys.exit(1) 178 179 if mirrors: 180 components = mirror_kernel_components(mirrors, components) 181 182 if options.validate: 183 components = select_kernel_components(components) 184 185 # Dump them out. 186 for component in components: 187 print " ".join(component) 188