1#!/bin/perl -w 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License, Version 1.0 only 7# (the "License"). You may not use this file except in compliance 8# with the License. 9# 10# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11# or http://www.opensolaris.org/os/licensing. 12# See the License for the specific language governing permissions 13# and limitations under the License. 14# 15# When distributing Covered Code, include this CDDL HEADER in each 16# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17# If applicable, add the following below this CDDL HEADER, with the 18# fields enclosed by brackets "[]" replaced with your own identifying 19# information: Portions Copyright [yyyy] [name of copyright owner] 20# 21# CDDL HEADER END 22# 23# 24# ident "%Z%%M% %I% %E% SMI" 25# 26# Copyright 2002 Sun Microsystems, Inc. All rights reserved. 27# Use is subject to license terms. 28# 29# ctfcvtptbl [-o outfile] patch-makeup-table 30# 31# Given a path to a patch makeup table, this script converts that table to 32# machine-optimal format and deposits it in the file specified by the -o option 33# or on stdout depending on whether or not -o is specified. 34# 35# The user-supplied patch makeup table is in the following format: 36# 37# # 38# # comment 39# # 40# 41# genunix_archive=/path/to/genunix/archive 42# 43# patch 100001-01 kureq 100002-01 44# usr/src/uts/sparc/sd/debug32/sd 45# module2 46# 47# patch 100003-08 48# module3 49# 50# The machine-optimal format for the above looks like this: 51# 52# GENUNIX_ARCHIVE=/path/to/genunix/archive 53# module1 100001-01 100002-01 54# module2 100001-01 100002-01 55# module3 100003-08 56# 57# 58# Macros and other time-savers: 59# 60# * $RELEASE and $MACH in the genunix archive path will be replaced by the 61# values of the RELEASE and MACH environment variables, respectively, as 62# set by the program calling this one. 63# 64# * BUILD, BUILD32, and BUILD64 will, when used in the path for the module, 65# will be match as follows: 66# 67# BUILD debug32, debug64, obj32, obj64 68# BUILD32 debug32, obj32 69# BUILD64 debug64, obj64 70# 71# * The presence of `usr/src' at the beginning of each module path will be 72# assumed, and is not required to be specified. 73# 74 75use strict; 76use Getopt::Std; 77use File::Basename; 78 79my $PROGNAME = basename($0); 80 81my $genunix_archive; 82my %moddata; 83my %typehash = ( 84 BUILD => [ "debug32", "debug64", "obj32", "obj64" ], 85 BUILD32 => [ "debug32", "obj32" ], 86 BUILD64 => [ "debug64", "obj64" ] 87); 88 89my %opts; 90my $err = 0; 91$err = 1 unless getopts("ho:", \%opts); 92if ($opts{"o"}) { 93 close(STDOUT); 94 open(STDOUT, ">" . $opts{"o"}) || do { 95 print STDERR "Couldn't open " . $opts{"o"} . ": $!\n"; 96 exit(1); 97 } 98} 99if ($opts{"h"}) { 100 &usage; 101 exit(2); 102} 103 104if (@ARGV != 1) { 105 $err = 1; 106} 107 108if ($err) { 109 &usage; 110 exit(2); 111} 112 113$::table = $ARGV[0]; 114 115if (!open(TABLE, "<$::table")) { 116 print STDERR "Couldn't open $::table: $!\n"; 117 exit(1); 118} 119 120if (!&read_table) { 121 exit(1); 122} 123 124&sub_vars; 125 126&dump_table; 127 128exit(0); 129 130sub usage { 131 print STDERR "Usage: $PROGNAME [-o outfile] table\n"; 132} 133 134sub read_table { 135 my $patchid = ""; 136 my $kureq = ""; 137 my $kuprev = ""; 138 139 $genunix_archive = ""; 140 undef %moddata; 141 142 while (<TABLE>) { 143 chop; 144 s/\#.*$//; # Strip comments 145 s/^\s+//; 146 147 if (!$patchid && /^genunix_archive=(\S+)\s*$/) { 148 $genunix_archive = $1; 149 next; 150 } 151 152 while ($_) { 153 if (s/^patch\s+(\d{6}-\d{2}) 154 (\s+ku(req|prev)\s+(\d{6}-\d{2}|fcs))?//x && 155 (!$_ || /^\s/)) { 156 $patchid = $1; 157 $kureq = (defined $4 ? $4 : "fcs"); 158 $kuprev = (defined $3 && $3 eq "prev" ? 1 : 0); 159 } elsif ($patchid && s/^(\S+)//) { 160 my $module = $1; 161 162 if (($module =~ m:/genunix/:) && !$kuprev) { 163 &parseerror("No kuprev supplied " . 164 "for entry including genunix"); 165 } 166 167 if (($module !~ m:^usr/src/:)) { 168 $module = "usr/src/" . $module; 169 } 170 171 if (($module =~ 172 m:^(.*)\$(BUILD|BUILD32|BUILD64)(/.*)$:)) { 173 foreach my $type (@{$typehash{$2}}) { 174 $moddata{$1 . $type . $3} = 175 [$patchid, $kureq]; 176 } 177 } else { 178 $moddata{$module} = [$patchid, $kureq]; 179 } 180 } else { 181 &parseerror("Cannot parse table"); 182 } 183 184 s/^\s+//; 185 } 186 } 187 188 if (!$genunix_archive) { 189 print STDERR "No genunix_archive line in table\n"; 190 return (0); 191 } 192 193 if (!%moddata) { 194 print STDERR "No module information read\n"; 195 return (0); 196 } 197 198 return (1); 199} 200 201sub parseerror { 202 my $msg = $_[0]; 203 204 print STDERR "$msg at line $.\n"; 205 exit(1); 206} 207 208sub sub_vars { 209 my $release = $ENV{"RELEASE"}; 210 my $mach = $ENV{"MACH"}; 211 212 $genunix_archive =~ s/\$RELEASE/$release/ if defined $release; 213 $genunix_archive =~ s/\$MACH/$mach/ if defined $mach; 214} 215 216sub dump_table { 217 print "GENUNIX_ARCHIVE=" . $genunix_archive . "\n"; 218 219 foreach my $mod (sort keys %moddata) { 220 print join(" ", ($mod, @{$moddata{$mod}})) . "\n"; 221 } 222} 223