MAKEDEV.awk revision 1.16
1#!/usr/bin/awk - 2# 3# $NetBSD: MAKEDEV.awk,v 1.16 2005/06/14 20:47:46 he Exp $ 4# 5# Copyright (c) 2003 The NetBSD Foundation, Inc. 6# All rights reserved. 7# 8# This code is derived from software contributed to The NetBSD Foundation 9# by Jaromir Dolecek. 10# 11# Redistribution and use in source and binary forms, with or without 12# modification, are permitted provided that the following conditions 13# are met: 14# 1. Redistributions of source code must retain the above copyright 15# notice, this list of conditions and the following disclaimer. 16# 2. Redistributions in binary form must reproduce the above copyright 17# notice, this list of conditions and the following disclaimer in the 18# documentation and/or other materials provided with the distribution. 19# 3. All advertising materials mentioning features or use of this software 20# must display the following acknowledgement: 21# This product includes software developed by the NetBSD 22# Foundation, Inc. and its contributors. 23# 4. Neither the name of The NetBSD Foundation nor the names of its 24# contributors may be used to endorse or promote products derived 25# from this software without specific prior written permission. 26# 27# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37# POSSIBILITY OF SUCH DAMAGE. 38# 39 40# Script to generate platform MAKEDEV script from MI template, MD 41# MAKEDEV.conf and MD/MI major lists 42# 43# Uses environment variables MACHINE/MACHINE_ARCH to select 44# appropriate files, and NETBSDSRCDIR to get root of source tree. 45 46BEGIN { 47 # top of source tree, used to find major number list in kernel 48 # sources 49 machine = ENVIRON["MACHINE"] 50 maarch = ENVIRON["MACHINE_ARCH"] 51 srcdir = ENVIRON["NETBSDSRCDIR"] 52 if (!machine || !maarch || !srcdir) { 53 print "ERROR: 'MACHINE', 'MACHINE_ARCH' and 'NETBSDSRCDIR' must be set in environment" > "/dev/stderr" 54 exit 1 55 } 56 top = srcdir "/sys/" 57 if (system("test -d '" top "'") != 0) { 58 print "ERROR: can't find top of kernel source tree ('" top "' not a directory)" > "/dev/stderr" 59 exit 1 60 } 61 62 63 # file with major definitions 64 majors[0] = "conf/majors" 65 if ((maarch == "arm" || maarch == "armeb") && system("test -f '" top "arch/" machine "/conf/majors." machine "'") != 0) 66 majors[1] = "arch/arm/conf/majors.arm32"; 67 else if (machine == "evbsh5") { 68 majors[1] = "arch/evbsh5/conf/majors.evbsh5"; 69 majors[2] = "arch/sh5/conf/majors.sh5"; 70 } else if (machine == "sbmips") 71 majors[1] = "arch/evbmips/conf/majors.evbmips"; 72 else 73 majors[1] = "arch/" machine "/conf/majors." machine; 74 75 # process all files with majors and fill the chr[] and blk[] 76 # arrays, used in template processing 77 for (m in majors) { 78 file = top majors[m] 79 if (system("test -f '" file "'") != 0) { 80 print "ERROR: can't find majors file '" file "'" > "/dev/stderr" 81 exit 1 82 } 83 while (getline < file) { 84 if ($1 == "device-major") { 85 if ($3 == "char") { 86 chr[$2] = $4 87 if ($5 == "block") 88 blk[$2] = $6 89 } else if ($3 == "block") 90 blk[$2] = $4 91 } 92 } 93 close(file) 94 } 95 96 # read MD config file for MD device targets 97 cfgfile = srcdir "/etc/etc." machine "/MAKEDEV.conf" 98 if (system("test -f '" cfgfile "'") != 0) { 99 print "ERROR: no platform MAKEDEV.conf - '" cfgfile "' doesn't exist" > "/dev/stderr" 100 exit 1 101 } 102 # skip first two lines 103 getline CONFRCSID < cfgfile # RCS Id 104 getline < cfgfile # blank line 105 MDDEV = 0 # MD device targets 106 while (getline < cfgfile) { 107 if (MDDEV) 108 MDDEV = MDDEV "\n" $0 109 else 110 MDDEV = $0 111 } 112 close(cfgfile) 113 114 # determine number of partitions used by platform 115 # there are three variants in tree: 116 # 1. MAXPARTITIONS = 8 117 # 2. MAXPARTITIONS = 16 with no back compat mapping 118 # 3. MAXPARTITIONS = 16 with back compat with old limit of 8 119 # currently all archs, which moved from 8->16 use same 120 # scheme for mapping disk minors, high minor offset 121 # if this changes, the below needs to be adjusted and 122 # additional makedisk_p16foo needs to be added 123 incdir = machine 124 diskpartitions = 0 125 diskbackcompat = 0 126 while (1) { 127 inc = top "arch/" incdir "/include/disklabel.h" 128 if (system("test -f '" inc "'") != 0) { 129 print "ERROR: can't find kernel include file '" inc "'" > "/dev/stderr" 130 exit 1 131 } 132 incdir = 0 133 while (getline < inc) { 134 if ($1 == "#define" && $2 == "MAXPARTITIONS") 135 diskpartitions = $3 136 else if ($1 == "#define" && $2 == "OLDMAXPARTITIONS") 137 diskbackcompat = $3 138 else if ($1 == "#define" && $2 == "RAW_PART") 139 RAWDISK_OFF = $3 140 else if ($1 == "#include" && 141 $2 ~ "<.*/disklabel.h>" && 142 $2 !~ ".*nbinclude.*") 143 { 144 # wrapper, switch to the right file 145 incdir = substr($2, 2) 146 sub("/.*", "", incdir) 147 break; 148 } 149 } 150 close(inc) 151 152 if (diskpartitions) 153 break; 154 155 if (!incdir) { 156 print "ERROR: can't determine MAXPARTITIONS from include file '" inc "'" > "/dev/stderr" 157 exit 1 158 } 159 } 160 MKDISK = "makedisk_p" diskpartitions # routine to create disk devs 161 DISKMINOROFFSET = diskpartitions 162 if (diskbackcompat) { 163 MKDISK = MKDISK "high" 164 DISKMINOROFFSET = diskbackcompat 165 } 166 RAWDISK_NAME = sprintf("%c", 97 + RAWDISK_OFF) # a+offset 167 168 # read etc/master.passwd for user name->UID mapping 169 idfile = srcdir "/etc/master.passwd" 170 if (system("test -f '" idfile "'") != 0) { 171 print "ERROR: can't find password file '" idfile "'" > "/dev/stderr" 172 exit 1 173 } 174 oldFS=FS 175 FS=":" 176 while (getline < idfile) { 177 uid[$1] = $3 178 } 179 close(idfile) 180 FS=oldFS 181 182 # read etc/group for group name->GID mapping 183 idfile = srcdir "/etc/group" 184 if (system("test -f '" idfile "'") != 0) { 185 print "ERROR: can't find group file '" idfile "'" > "/dev/stderr" 186 exit 1 187 } 188 oldFS=FS 189 FS=":" 190 while (getline < idfile) { 191 gid[$1] = $3 192 } 193 close(idfile) 194 FS=oldFS 195 196 # initially no substitutions 197 devsubst = 0 198 deventry = "" 199} 200 201/%MI_DEVICES_BEGIN%/ { 202 devsubst = 1; 203 next 204} 205 206/%MI_DEVICES_END%/ { 207 devsubst = 0; 208 next 209} 210 211# output 'Generated from' lines 212/\$[N]etBSD/ { 213 print "#" 214 print "# Generated from:" 215 216 # MAKEDEV.awk (this script) RCS Id 217 ARCSID = "$NetBSD: MAKEDEV.awk,v 1.16 2005/06/14 20:47:46 he Exp $" 218 gsub(/\$/, "", ARCSID) 219 print "# " ARCSID 220 221 # MAKEDEV.tmpl RCS Id 222 gsub(/\$/, "") 223 print $0 224 225 # MD MAKEDEV.conf RCS Id 226 # strip leading hash and insert machine subdirectory name 227 gsub(/\$/, "", CONFRCSID) 228 sub(/^\# /, "", CONFRCSID) 229 sub(/MAKEDEV.conf/, "etc." machine "/MAKEDEV.conf", CONFRCSID) 230 print "# " CONFRCSID 231 232 next # don't print the RCS Id line again 233} 234 235# filter the 'PLEASE RUN ...' paragraph 236/^\# PLEASE RUN/, /^\#\#\#\#\#\#/ { 237 next 238} 239 240# filter the device list 241/^\# Tapes/,/^$/ { 242 next 243} 244 245# filter the two unneeded makedisk_p* routines, leave only 246# the one used 247/^makedisk_p8\(\) \{/, /^\}/ { 248 if (MKDISK != "makedisk_p8") 249 next; 250} 251/^makedisk_p16\(\) \{/, /^\}/ { 252 if (MKDISK != "makedisk_p16") 253 next; 254} 255/^makedisk_p16high\(\) \{/, /^\}/ { 256 if (MKDISK != "makedisk_p16high") 257 next; 258} 259 260# special cases aside, handle normal line 261{ 262 sub(/^%MD_DEVICES%/, MDDEV) 263 sub(/%MKDISK%/, MKDISK) 264 sub(/%DISKMINOROFFSET%/, DISKMINOROFFSET) 265 sub(/%RAWDISK_OFF%/, RAWDISK_OFF) 266 sub(/%RAWDISK_NAME%/, RAWDISK_NAME) 267 parsed = "" 268 line = $0 269 while (match(line, /%[gu]id_[a-z]*%/)) { 270 typ = substr(line, RSTART + 1, 3); 271 nam = substr(line, RSTART + 5, RLENGTH - 6); 272 if (typ == "uid") { 273 if (!(nam in uid)) { 274 print "ERROR unmatched uid in `" $0 "'" > \ 275 "/dev/stderr" 276 exit 1 277 } else 278 id = uid[nam]; 279 } else { 280 if (!(nam in gid)) { 281 print "ERROR unmatched gid in `" $0 "'" > \ 282 "/dev/stderr" 283 exit 1 284 } else 285 id = gid[nam]; 286 } 287 parsed = parsed substr(line, 1, RSTART - 1) id 288 line = substr(line, RSTART + RLENGTH) 289 } 290 $0 = parsed line 291 292 # if device substitutions are not active, do nothing more 293 if (!devsubst) { 294 print 295 next 296 } 297} 298 299# first line of device entry 300/^[a-z].*\)$/ { 301 if (length(deventry) > 0) { 302 # We have a previous entry to print. Replace all known 303 # character and block devices. If no unknown character 304 # or block device definition remains within the entry, 305 # print it to output, otherwise scrap it. 306 parsed = "" 307 while (match(deventry, /%[a-z]*_(blk|chr)%/)) { 308 nam = substr(deventry, RSTART + 1, RLENGTH - 6); 309 typ = substr(deventry, RSTART + RLENGTH - 4, 3); 310 if (typ == "blk") { 311 if (!(nam in blk)) { 312 deventry = $0 313 next 314 } else 315 dev = blk[nam]; 316 } else { 317 if (!(nam in chr)) { 318 deventry = $0 319 next 320 } else 321 dev = chr[nam]; 322 } 323 parsed = parsed substr(deventry, 1, RSTART - 1) dev 324 deventry = substr(deventry, RSTART + RLENGTH) 325 } 326 327 print parsed deventry 328 } 329 deventry = $0 330 next 331} 332 333# template line within device substitution section - just keep appending 334# to the current entry 335{ 336 deventry = deventry "\n" $0 337} 338