1#!/bin/bin/perl -w 2# 3# Copyright (C) 2006, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") 4# 5# Permission to use, copy, modify, and/or distribute this software for any 6# purpose with or without fee is hereby granted, provided that the above 7# copyright notice and this permission notice appear in all copies. 8# 9# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15# PERFORMANCE OF THIS SOFTWARE. 16 17# Id: spnego_asn1.pl,v 1.4 2007/06/19 23:47:16 tbox Exp 18 19# Our SPNEGO implementation uses some functions generated by the 20# Heimdal ASN.1 compiler, which this script then whacks a bit to make 21# them work properly in this stripped down implementation. We don't 22# want to require our users to have a copy of the compiler, so we ship 23# the output of this script, but we need to keep the script around in 24# any case to cope with future changes to the SPNEGO ASN.1 code, so we 25# might as well supply the script for users who want it. 26 27# Overall plan: run the ASN.1 compiler, run each of its output files 28# through indent, fix up symbols and whack everything to be static. 29# We use indent for two reasons: (1) to whack the Heimdal compiler's 30# output into something closer to ISC's coding standard, and (2) to 31# make it easier for this script to parse the result. 32 33# Output from this script is C code which we expect to be #included 34# into another C file, which is why everything generated by this 35# script is marked "static". The intent is to minimize the number of 36# extern symbols exported by the SPNEGO implementation, to avoid 37# potential conflicts with the GSSAPI libraries. 38 39### 40 41# Filename of the ASN.1 specification. Hardcoded for the moment 42# since this script is intended for compiling exactly one module. 43 44my $asn1_source = $ENV{ASN1_SOURCE} || "spnego.asn1"; 45 46# Heimdal ASN.1 compiler. This script was written using the version 47# from Heimdal 0.7.1. To build this, download a copy of 48# heimdal-0.7.1.tar.gz, configure and build with the default options, 49# then look for the compiler in heimdal-0.7.1/lib/asn1/asn1_compile. 50 51my $asn1_compile = $ENV{ASN1_COMPILE} || "asn1_compile"; 52 53# BSD indent program. This script was written using the version of 54# indent that comes with FreeBSD 4.11-STABLE. The GNU project, as 55# usual, couldn't resist the temptation to monkey with indent's 56# command line syntax, so this probably won't work with GNU indent. 57 58my $indent = $ENV{INDENT} || "indent"; 59 60### 61 62# Step 1: run the compiler. Input is the ASN.1 file. Outputs are a 63# header file (name specified on command line without the .h suffix), 64# a file called "asn1_files" listing the names of the other output 65# files, and a set of files containing C code generated by the 66# compiler for each data type that the compiler found. 67 68if (! -r $asn1_source || system($asn1_compile, $asn1_source, "asn1")) { 69 die("Couldn't compile ASN.1 source file $asn1_source\n"); 70} 71 72my @files = ("asn1.h"); 73 74open(F, "asn1_files") 75 or die("Couldn't open asn1_files: $!\n"); 76push(@files, split) 77 while (<F>); 78close(F); 79 80unlink("asn1_files"); 81 82### 83 84# Step 2: generate header block. 85 86print(q~/* 87 * Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC") 88 * 89 * Permission to use, copy, modify, and distribute this software for any 90 * purpose with or without fee is hereby granted, provided that the above 91 * copyright notice and this permission notice appear in all copies. 92 * 93 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 94 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 95 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 96 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 97 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 98 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 99 * PERFORMANCE OF THIS SOFTWARE. 100 */ 101 102/* Id: spnego_asn1.pl,v 1.4 2007/06/19 23:47:16 tbox Exp */ 103 104/*! \file 105 * \brief Method routines generated from SPNEGO ASN.1 module. 106 * See spnego_asn1.pl for details. Do not edit. 107 */ 108 109~); 110 111### 112 113# Step 3: read and process each generated file, then delete it. 114 115my $output; 116 117for my $file (@files) { 118 119 my $is_static = 0; 120 121 system($indent, "-di1", "-ldi1", $file) == 0 122 or die("Couldn't indent $file"); 123 124 unlink("$file.BAK"); 125 126 open(F, $file) 127 or die("Couldn't open $file: $!"); 128 129 while (<F>) { 130 131 # Symbol name fixups 132 133 s/heim_general_string/general_string/g; 134 s/heim_octet_string/octet_string/g; 135 s/heim_oid/oid/g; 136 s/heim_utf8_string/utf8_string/g; 137 138 # Convert all externs to statics 139 140 if (/^static/) { 141 $is_static = 1; 142 } 143 144 if (!/^typedef/ && 145 !$is_static && 146 /^[A-Za-z_][0-9A-Za-z_]*[ \t]*($|[^:0-9A-Za-z_])/) { 147 $_ = "static " . $_; 148 $is_static = 1; 149 } 150 151 if (/[{};]/) { 152 $is_static = 0; 153 } 154 155 # Suppress file inclusion, pass anything else through 156 157 if (!/#include/) { 158 $output .= $_; 159 } 160 } 161 162 close(F); 163 unlink($file); 164} 165 166# Step 4: Delete unused stuff to avoid code bloat and compiler warnings. 167 168my @unused_functions = qw(ContextFlags2int 169 int2ContextFlags 170 asn1_ContextFlags_units 171 length_NegTokenInit 172 copy_NegTokenInit 173 length_NegTokenResp 174 copy_NegTokenResp 175 length_MechTypeList 176 length_MechType 177 copy_MechTypeList 178 length_ContextFlags 179 copy_ContextFlags 180 copy_MechType); 181 182$output =~ s<^static [^\n]+\n$_\(.+?^}></* unused function: $_ */\n>ms 183 foreach (@unused_functions); 184 185$output =~ s<^static .+$_\(.*\);$></* unused declaration: $_ */>m 186 foreach (@unused_functions); 187 188$output =~ s<^static struct units ContextFlags_units\[\].+?^};> 189 </* unused variable: ContextFlags_units */>ms; 190 191$output =~ s<^static int asn1_NegotiationToken_dummy_holder = 1;> 192 </* unused variable: asn1_NegotiationToken_dummy_holder */>ms; 193 194$output =~ s<^static void\nfree_ContextFlags\(ContextFlags \* data\)\n{\n> 195 <$&\t(void)data;\n>ms; 196 197# Step 5: Write the result. 198 199print($output); 200 201