1#!/usr/bin/perl 2 3# 4# Generate the AUTHORS file combining existing AUTHORS file with 5# git commit log. 6# 7# Usage: generate_authors.pl AUTHORS.src 8 9# 10# Copyright 2016 Michael Mann (see AUTHORS file) 11# 12# Wireshark - Network traffic analyzer 13# By Gerald Combs <gerald@wireshark.org> 14# Copyright 1998 Gerald Combs 15# 16# SPDX-License-Identifier: GPL-2.0-or-later 17 18use warnings; 19use strict; 20use Getopt::Long; 21use Encode qw(encode decode); 22 23my $state = ""; 24my %contributors = (); 25my $is_contributing = 0; 26 27my $header = " 28 29= Original Author = 30 31Gerald Combs <gerald[AT]wireshark.org> 32 33 34"; 35 36my $trailer = " 37 38= Acknowledgements = 39 40Dan Lasley <dlasley[AT]promus.com> gave permission for his dumpit() hex-dump routine to be used. 41 42Mattia Cazzola <mattiac[AT]alinet.it> provided a patch to the hex dump display routine. 43 44We use the exception module from Kazlib, a C library written by Kaz Kylheku <kaz[AT]kylheku.com>. Thanks go to him for his well-written library. The Kazlib home page can be found at http://www.kylheku.com/~kaz/kazlib.html 45 46We use Lua BitOp, written by Mike Pall, for bitwise operations on numbers in Lua. The Lua BitOp home page can be found at https://bitop.luajit.org 47 48snax <snax[AT]shmoo.com> gave permission to use his(?) weak key detection code from Airsnort. 49 50IANA gave permission for their port-numbers file to be used. 51 52We use the natural order string comparison algorithm, written by Martin Pool <mbp[AT]sourcefrog.net>. 53 54Emanuel Eichhammer <support[AT]qcustomplot.com> granted permission to use QCustomPlot. 55 56Insecure.Com LLC (\"The Nmap Project\") has granted the Wireshark Foundation permission to distribute Npcap with our Windows installers. 57"; 58 59my $git_log_text = " 60= From git log = 61 62"; 63 64# Perl trim function to remove whitespace from the start and end of the string 65sub trim($) 66{ 67 my $string = shift; 68 $string =~ s/^\s+//; 69 $string =~ s/\s+$//; 70 return $string; 71} 72 73sub parse_author_name { 74 my $full_name = $_[0]; 75 my $email_key; 76 77 if ($full_name =~ /^([\w\.\-\'\x80-\xff]+(\s*[\w+\.\-\'\x80-\xff])*)\s+<([^>]*)>/) { 78 #Make an exception for Gerald because he's part of the header 79 if ($3 ne "gerald[AT]wireshark.org") { 80 $email_key = lc($3); 81 $contributors{$email_key} = $1; 82 print encode('UTF-8', "$full_name\n"); 83 } 84 } elsif ($full_name =~ /^([\w\.\-\'\x80-\xff]+(\s*[\w+\.\-\'\x80-\xff])*)\s+\(/) { 85 $contributors{"<no_email>"} = $1; 86 print encode('UTF-8', "$full_name\n"); 87 } 88} 89 90sub parse_git_name { 91 my $full_name = $_[0]; 92 my $name; 93 my $email; 94 my $email_key; 95 my $len; 96 my $ntab = 3; 97 my $line; 98 99 # 4321 Navin R. Johnson <nrjohnson@example.com> 100 if ($full_name =~ /^\s*\d+\s+([^<]*)\s*<([^>]*)>/) { 101 $name = trim($1); 102 #Convert real email address to "spam proof" one 103 $email = trim($2); 104 $email =~ s/@/[AT]/g; 105 $email_key = lc($email); 106 107 if (!exists($contributors{ $email_key })) { 108 #Make an exception for Gerald because he's part of the header 109 if ($email ne "gerald[AT]wireshark.org") { 110 $len = length $name; 111 if ($len >= 8 * $ntab) { 112 $line = "$name <$email>"; 113 } else { 114 $ntab -= $len / 8; 115 $ntab +=1 if ($len % 8); 116 $line = $name . "\t" x $ntab . "<$email>"; 117 } 118 $contributors{$email_key} = $1; 119 print encode('UTF-8', "$line\n"); 120 } 121 } 122 } 123} 124 125# --------------------------------------------------------------------- 126# 127# MAIN 128# 129 130print $header; 131 132open( my $author_fh, '<', $ARGV[0] ) or die "Can't open $ARGV[0]: $!"; 133while ( my $line = decode('UTF-8', <$author_fh>) ) { 134 chomp $line; 135 136 last if ($line =~ "Acknowledgements"); 137 138 if ($line =~ "Contributors") { 139 $is_contributing = 1; 140 } elsif ($is_contributing == 0) { 141 next; 142 } 143 144 if ($line =~ /([^\{]*)\{/) { 145 parse_author_name($line); 146 $state = "s_in_bracket"; 147 } elsif ($state eq "s_in_bracket") { 148 if ($line =~ /([^\}]*)\}/) { 149 print encode('UTF-8', "$line\n"); 150 $state = ""; 151 } else { 152 print encode('UTF-8', "$line\n"); 153 } 154 } elsif ($line =~ /</) { 155 parse_author_name($line); 156 } elsif ($line =~ "(e-mail address removed at contributor's request)") { 157 parse_author_name($line); 158 } else { 159 print encode('UTF-8', "$line\n"); 160 } 161} 162close $author_fh; 163 164print $git_log_text; 165 166open( my $git_author_fh, 'git --no-pager shortlog -se HEAD|') 167 or die "Can't execute git shortlog: $!"; 168 169while ( my $git_line = decode('UTF-8', <$git_author_fh>) ) { 170 chomp $git_line; 171 172 parse_git_name($git_line); 173} 174close $git_author_fh; 175 176print $trailer; 177 178__END__ 179