Permit null ciphers.
[openssl.git] / util / mkdef.pl
1 #!/usr/local/bin/perl
2 #
3 # generate a .def file
4 #
5 # It does this by parsing the header files and looking for the
6 # non-prototyped functions.
7 #
8
9 $crypto_num="util/libeay.num";
10 $ssl_num=   "util/ssleay.num";
11
12 $W32=1;
13 $NT=0;
14 foreach (@ARGV)
15         {
16         $W32=1 if $_ eq "32";
17         $W32=0 if $_ eq "16";
18         if($_ eq "NT") {
19                 $W32 = 1;
20                 $NT = 1;
21         }
22         $do_ssl=1 if $_ eq "ssleay";
23         $do_ssl=1 if $_ eq "ssl";
24         $do_crypto=1 if $_ eq "libeay";
25         $do_crypto=1 if $_ eq "crypto";
26         $do_update=1 if $_ eq "update";
27         }
28
29 if (!$do_ssl && !$do_crypto)
30         {
31         print STDERR "usage: $0 ( ssl | crypto ) [ 16 | 32 ]\n";
32         exit(1);
33         }
34
35 %ssl_list=&load_numbers($ssl_num);
36 $max_ssl = $max_num;
37 %crypto_list=&load_numbers($crypto_num);
38 $max_crypto = $max_num;
39
40 $ssl="ssl/ssl.h";
41
42 $crypto ="crypto/crypto.h";
43 $crypto.=" crypto/des/des.h";
44 $crypto.=" crypto/idea/idea.h";
45 $crypto.=" crypto/rc4/rc4.h";
46 $crypto.=" crypto/rc5/rc5.h";
47 $crypto.=" crypto/rc2/rc2.h";
48 $crypto.=" crypto/bf/blowfish.h";
49 $crypto.=" crypto/cast/cast.h";
50 $crypto.=" crypto/md2/md2.h";
51 $crypto.=" crypto/md5/md5.h";
52 $crypto.=" crypto/mdc2/mdc2.h";
53 $crypto.=" crypto/sha/sha.h";
54 $crypto.=" crypto/ripemd/ripemd.h";
55
56 $crypto.=" crypto/bn/bn.h";
57 $crypto.=" crypto/rsa/rsa.h";
58 $crypto.=" crypto/dsa/dsa.h";
59 $crypto.=" crypto/dh/dh.h";
60
61 $crypto.=" crypto/stack/stack.h";
62 $crypto.=" crypto/buffer/buffer.h";
63 $crypto.=" crypto/bio/bio.h";
64 $crypto.=" crypto/lhash/lhash.h";
65 $crypto.=" crypto/conf/conf.h";
66 $crypto.=" crypto/txt_db/txt_db.h";
67
68 $crypto.=" crypto/evp/evp.h";
69 $crypto.=" crypto/objects/objects.h";
70 $crypto.=" crypto/pem/pem.h";
71 #$crypto.=" crypto/meth/meth.h";
72 $crypto.=" crypto/asn1/asn1.h";
73 $crypto.=" crypto/asn1/asn1_mac.h";
74 $crypto.=" crypto/err/err.h";
75 $crypto.=" crypto/pkcs7/pkcs7.h";
76 $crypto.=" crypto/x509/x509.h";
77 $crypto.=" crypto/x509/x509_vfy.h";
78 $crypto.=" crypto/x509v3/x509v3.h";
79 $crypto.=" crypto/rand/rand.h";
80 $crypto.=" crypto/hmac/hmac.h";
81 $crypto.=" crypto/comp/comp.h";
82 $crypto.=" crypto/tmdiff.h";
83
84 $match{'NOPROTO'}=1;
85 $match2{'PERL5'}=1;
86
87 @ssl_func = &do_defs("SSLEAY", $ssl);
88 @crypto_func = &do_defs("LIBEAY", $crypto);
89
90 if ($do_update) {
91
92 if ($do_ssl == 1) {
93         open(OUT, ">>$ssl_num");
94         &update_numbers(*OUT,"SSLEAY",*ssl_list,$max_ssl, @ssl_func);
95         close OUT;
96 }
97
98 if($do_crypto == 1) {
99         open(OUT, ">>$crypto_num");
100         &update_numbers(*OUT,"LIBEAY",*crypto_list,$max_crypto, @crypto_func);
101         close OUT;
102 }
103
104 } else {
105
106         &print_def_file(*STDOUT,"SSLEAY",*ssl_list,@ssl_func)
107                 if $do_ssl == 1;
108
109         &print_def_file(*STDOUT,"LIBEAY",*crypto_list,@crypto_func)
110                 if $do_crypto == 1;
111
112 }
113
114
115 sub do_defs
116         {
117         local($name,$files)=@_;
118         local(@ret);
119
120         $off=-1;
121         foreach $file (split(/\s+/,$files))
122                 {
123 #               print STDERR "reading $file\n";
124                 open(IN,"<$file") || die "unable to open $file:$!\n";
125                 $depth=0;
126                 $pr=-1;
127                 @np="";
128                 $/=undef;
129                 $a=<IN>;
130                 while (($i=index($a,"/*")) >= 0)
131                         {
132                         $j=index($a,"*/");
133                         last unless ($j >= 0);
134                         $a=substr($a,0,$i).substr($a,$j+2);
135                 #       print "$i $j\n";
136                         }
137                 foreach (split("\n",$a))
138                         {
139                         if (/^\#\s*ifndef (.*)/)
140                                 {
141                                 push(@tag,$1);
142                                 $tag{$1}=-1;
143                                 next;
144                                 }
145                         elsif (/^\#\s*if !defined\(([^\)]+)\)/)
146                                 {
147                                 push(@tag,$1);
148                                 $tag{$1}=-1;
149                                 next;
150                                 }
151                         elsif (/^\#\s*ifdef (.*)/)
152                                 {
153                                 push(@tag,$1);
154                                 $tag{$1}=1;
155                                 next;
156                                 }
157                         elsif (/^\#\s*if defined(.*)/)
158                                 {
159                                 push(@tag,$1);
160                                 $tag{$1}=1;
161                                 next;
162                                 }
163                         elsif (/^\#\s*endif/)
164                                 {
165                                 $tag{$tag[$#tag]}=0;
166                                 pop(@tag);
167                                 next;
168                                 }
169                         elsif (/^\#\s*else/)
170                                 {
171                                 $t=$tag[$#tag];
172                                 $tag{$t}= -$tag{$t};
173                                 next;
174                                 }
175 #printf STDERR "$_\n%2d %2d %2d %2d %2d $W32\n",
176 #$tag{'NOPROTO'},$tag{'FreeBSD'},$tag{'WIN16'},$tag{'PERL5'},$tag{'NO_FP_API'};
177
178                         $t=undef;
179                         if (/^extern .*;$/)
180                                 { $t=&do_extern($name,$_); }
181                         elsif ( ($tag{'NOPROTO'} == 1) &&
182                                 ($tag{'FreeBSD'} != 1) &&
183                                 (($W32 && ($tag{'WIN16'} != 1)) ||
184                                  (!$W32 && ($tag{'WIN16'} != -1))) &&
185                                 ($tag{'PERL5'} != 1) &&
186 #                               ($tag{'_WINDLL'} != -1) &&
187                                 ((!$W32 && $tag{'_WINDLL'} != -1) ||
188                                  ($W32 && $tag{'_WINDLL'} != 1)) &&
189                                 ((($tag{'NO_FP_API'} != 1) && $W32) ||
190                                  (($tag{'NO_FP_API'} != -1) && !$W32)))
191                                 { $t=&do_line($name,$_); }
192                         else
193                                 { $t=undef; }
194                         if (($t ne undef) && (!$done{$name,$t}))
195                                 {
196                                 $done{$name,$t}++;
197                                 push(@ret,$t);
198 #printf STDERR "one:$t\n" if $t =~ /BIO_/;
199                                 }
200                         }
201                 close(IN);
202                 }
203         return(@ret);
204         }
205
206 sub do_line
207         {
208         local($file,$_)=@_;
209         local($n);
210
211         return(undef) if /^$/;
212         return(undef) if /^\s/;
213 #printf STDERR "two:$_\n" if $_ =~ /BIO_/;
214         if (/(CRYPTO_get_locking_callback)/)
215                 { return($1); }
216         elsif (/(CRYPTO_get_id_callback)/)
217                 { return($1); }
218         elsif (/(CRYPTO_get_add_lock_callback)/)
219                 { return($1); }
220         elsif (/(SSL_CTX_get_verify_callback)/)
221                 { return($1); }
222         elsif (/(SSL_get_info_callback)/)
223                 { return($1); }
224         elsif ((!$W32) && /(ERR_load_CRYPTO_strings)/)
225                 { return("ERR_load_CRYPTOlib_strings"); }
226         elsif (!$W32 && /BIO_s_file/)
227                 { return(undef); }
228         elsif (!$W32 && /BIO_new_file/)
229                 { return(undef); }
230         elsif (!$W32 && /BIO_new_fp/)
231                 { return(undef); }
232         elsif ($W32 && /BIO_s_file_internal/)
233                 { return(undef); }
234         elsif ($W32 && /BIO_new_file_internal/)
235                 { return(undef); }
236         elsif ($W32 && /BIO_new_fp_internal/)
237                 { return(undef); }
238         elsif (/SSL_add_cert_dir_to_stack/)
239                 { return(undef); }
240         elsif (!$NT && /BIO_s_log/)
241                 { return(undef); }
242         else
243                 {
244                 /\s\**(\S+)\s*\(/;
245                 $_ = $1;
246                 tr/()*//d;
247 #print STDERR "$1 : $_\n";
248                 return($_);
249                 }
250         }
251
252 sub do_extern
253         {
254         local($file,$_)=@_;
255         local($n);
256
257         /\s\**(\S+);$/;
258         return($1);
259         }
260
261 sub print_def_file
262         {
263         local(*OUT,$name,*nums,@functions)=@_;
264         local($n)=1;
265
266         if ($W32)
267                 { $name.="32"; }
268         else
269                 { $name.="16"; }
270
271         print OUT <<"EOF";
272 ;
273 ; Definition file for the DLL version of the $name library from OpenSSL
274 ;
275
276 LIBRARY         $name
277
278 DESCRIPTION     'OpenSSL $name - http://www.openssl.org/'
279
280 EOF
281
282         if (!$W32)
283                 {
284                 print <<"EOF";
285 CODE            PRELOAD MOVEABLE
286 DATA            PRELOAD MOVEABLE SINGLE
287
288 EXETYPE         WINDOWS
289
290 HEAPSIZE        4096
291 STACKSIZE       8192
292
293 EOF
294                 }
295
296         print "EXPORTS\n";
297
298
299         (@e)=grep(/^SSLeay/,@functions);
300         (@r)=grep(!/^SSLeay/,@functions);
301         @functions=((sort @e),(sort @r));
302
303         foreach $func (@functions)
304                 {
305                 if (!defined($nums{$func}))
306                         {
307                         printf STDERR "$func does not have a number assigned\n"
308                                         if(!$do_update);
309                         }
310                 else
311                         {
312                         $n=$nums{$func};
313                         printf OUT "    %s%-40s@%d\n",($W32)?"":"_",$func,$n;
314                         }
315                 }
316         printf OUT "\n";
317         }
318
319 sub load_numbers
320         {
321         local($name)=@_;
322         local($j,@a,%ret);
323
324         $max_num = 0;
325
326         open(IN,"<$name") || die "unable to open $name:$!\n";
327         while (<IN>)
328                 {
329                 chop;
330                 s/#.*$//;
331                 next if /^\s*$/;
332                 @a=split;
333                 $ret{$a[0]}=$a[1];
334                 $max_num = $a[1] if $a[1] > $max_num;
335                 }
336         close(IN);
337         return(%ret);
338         }
339
340 sub update_numbers
341         {
342         local(*OUT,$name,*nums,$start_num, @functions)=@_;
343         my $new_funcs = 0;
344         print STDERR "Updating $name\n";
345         foreach $func (@functions)
346                 {
347                 if (!defined($nums{$func}))
348                         {
349                         $new_funcs++;
350                         printf OUT "%s%-40s%d\n","",$func, ++$start_num;
351                         }
352                 }
353         if($new_funcs) {
354                 print STDERR "$new_funcs New Functions added\n";
355         } else {
356                 print STDERR "No New Functions Added\n";
357         }
358         }