1:
2eval 'exec perl -wS $0 ${1+"$@"}'
3    if 0;
4#
5# This file is part of the LibreOffice project.
6#
7# This Source Code Form is subject to the terms of the Mozilla Public
8# License, v. 2.0. If a copy of the MPL was not distributed with this
9# file, You can obtain one at http://mozilla.org/MPL/2.0/.
10#
11# This file incorporates work covered by the following license notice:
12#
13#   Licensed to the Apache Software Foundation (ASF) under one or more
14#   contributor license agreements. See the NOTICE file distributed
15#   with this work for additional information regarding copyright
16#   ownership. The ASF licenses this file to you under the Apache
17#   License, Version 2.0 (the "License"); you may not use this file
18#   except in compliance with the License. You may obtain a copy of
19#   the License at http://www.apache.org/licenses/LICENSE-2.0 .
20#
21
22use strict;
23use Getopt::Long;
24
25my $debug = 0;
26my $max_files = 400;          # sign $max_files with one command line
27
28#### globals #####
29my $myname      = "";
30my $opt_desc    = "";
31my $opt_exclude = "";         # file with a list of not signable dll and exe files
32my $opt_verbose = 0;
33my $opt_help    = 0;
34my $opt_log     = "";         # for logging
35my $opt_pass    = "";         # password for signing
36my $opt_pfxfile = "";         # Personal Information Exchange file
37my $opt_timestamp_url = "";   # timestamp url
38my %exclude_files = ();       # list of not signable dll and exe files
39my $signtool    = "signtool.exe sign";
40my @args        = ();
41my @files_to_sign = ();
42
43#### main #####
44$myname = script_id();
45if ( $#ARGV < 2 ) {
46    usage();
47    exit(1);
48}
49@args = parse_options();
50get_exclude_files() if ($opt_exclude ne "");
51@files_to_sign = get_files(\@args);
52if ( $opt_log ) {               # logging
53    open(LOG,">$opt_log") || die "Can't open log file $opt_log\n";
54}
55sign_files(\@files_to_sign);
56close LOG if ($opt_log);        # logging
57exit 0;
58
59
60#### subroutines ####
61
62sub script_id
63{
64    ( my $script_name = $0 ) =~ s/^.*[\\\/]([\w\.]+)$/$1/;
65    return $script_name;
66}
67
68############################################################################
69sub parse_options       #09.07.2007 08:13
70############################################################################
71{
72    # e exclude list file
73    # v verbose
74    my $success = GetOptions('h' => \$opt_help,
75         'd=s' => \$opt_desc, 'e=s'=>\$opt_exclude, 'f=s'=>\$opt_pfxfile, 'l=s'=>\$opt_log,
76         'p=s'=>\$opt_pass,'v'=>\$opt_verbose, 't=s'=>\$opt_timestamp_url);
77    if ( !$success || $opt_help ) {
78        usage();
79        exit(1);
80    }
81    return @ARGV;
82}   ##parse_options
83
84############################################################################
85sub get_exclude_files       #09.07.2007 10:12
86############################################################################
87{
88    if ( -e $opt_exclude ) {
89            # get data from cache file
90            open( IN, "<$opt_exclude") || die "Can't open exclude file $opt_exclude\n";
91            while ( my $line = <IN> ) {
92            chomp($line);
93            $exclude_files{$line} = 1;          # fill hash
94            print "$line - $exclude_files{$line}\n" if ($debug);
95            }
96        } else
97        {
98            print_error("Can't open $opt_exclude file!\n");
99        }
100}   ##get_exclude_files
101
102############################################################################
103sub get_files       #10.07.2007 10:19
104############################################################################
105 {
106    use File::Basename;
107    my $target = shift;
108    my $file_pattern;
109    my $file;
110    my @files = ();
111    print "\n";
112    foreach $file_pattern ( @$target )
113    {
114        print "Files: $file_pattern\n";
115        foreach $file ( glob( $file_pattern ) )
116        {
117            my $lib = File::Basename::basename $file;
118            if ( ! $exclude_files{$lib} ) {
119                push @files,$file;
120            }
121            else
122            {
123                print "exclude=$lib\n" if ($opt_verbose);
124            }
125        }
126    }
127    print "\n";
128    return @files;
129}   ##get_files
130
131############################################################################
132sub sign_files      #09.07.2007 10:36
133############################################################################
134{
135    my $files_to_sign = shift;
136    my $commandline_base = ""; # contains whole stuff without the file name
137    my $file = "";
138    my $result = "";
139
140    if ( $opt_pass =~ /\.exe$/ ) {
141        # get password by tool
142        open(PIPE, "$opt_pass 2>&1 |") || die "Can't open PIPE!\n";
143        my $pass = <PIPE>;
144        close PIPE;
145        print_error("Can't get password!\n") if ( !$pass ); # exit here
146        $opt_pass = $pass;
147    }
148    $signtool .= " -v" if ($opt_verbose);
149    $commandline_base = $signtool;
150    $commandline_base .= " -f $opt_pfxfile" if ($opt_pfxfile ne "");
151    $commandline_base .= " -p $opt_pass" if ($opt_pass ne "");
152    $commandline_base .= " -t $opt_timestamp_url" if ($opt_timestamp_url ne "");
153    $commandline_base .= " -d \"$opt_desc\"" if ($opt_desc ne "");
154
155    # Here switch between:
156    # one command line for multiple files (all doesn't work, too much) / for each file one command line
157    if ( $max_files > 1 ) {
158        exec_multi_sign($files_to_sign, $commandline_base);
159    } else
160    {
161        exec_single_sign($files_to_sign, $commandline_base);
162    }
163}   ##sign_files
164
165############################################################################
166sub exec_single_sign        #11.07.2007 09:05
167############################################################################
168{
169    my $files_to_sign    = shift;
170    my $commandline_base = shift;                 # contains whole stuff without the file name
171    my $file = "";
172    my $commandline = "";
173
174    foreach $file (@$files_to_sign)
175    {
176        $commandline = $commandline_base . " $file";
177        print "$commandline\n" if ($debug);
178        execute($commandline);
179    } #foreach
180}   ##exec_single_sign
181
182############################################################################
183sub exec_multi_sign     #11.07.2007 08:56
184############################################################################
185 {
186    # sign multiple file with one command line
187    my $files_to_sign    = shift;
188    my $commandline_base = shift;                 # contains whole stuff without the file name
189    my $commandline = $commandline_base;          # contains stuff which will be executed
190    my $file = "";
191    my $counter = 0;
192
193    foreach $file (@$files_to_sign)
194    {
195        $commandline .= " $file";
196        ++$counter;
197        if ( $counter >= $max_files ) {
198            execute($commandline);
199            $counter = 0;                        # reset counter
200            $commandline = $commandline_base;    # reset command line
201        }
202    }
203    execute($commandline) if ($counter > 0);
204}   ##exec_multi_sign
205
206############################################################################
207sub execute     #11.07.2007 10:02
208############################################################################
209{
210    my $commandline = shift;
211    my $result = "";
212    my $errorlines = "";
213
214    print "$commandline\n" if ($debug);
215    open(PIPE, "$commandline 2>&1 |") || die "Error: Cannot execute '$commandline' - $!\n";
216    while ( $result = <PIPE> ) {
217        print LOG "$result" if ($opt_log);
218        $errorlines .= $result if ($result =~ /SignTool Error\:/);
219    } # while
220    close PIPE;
221    print_error( "$errorlines\n" ) if ($errorlines);
222}   ##execute
223
224############################################################################
225sub print_error     #09.07.2007 11:21
226############################################################################
227 {
228    my $text = shift;
229    print "ERROR: $text\n";
230    print LOG "ERROR: $text\n" if ($opt_log);        # logging
231    close LOG if ($opt_log);                         # logging
232    exit(1);
233}   ##print_error
234
235############################################################################
236sub usage       #09.07.2007 08:39
237############################################################################
238 {
239    print "Usage:\t $myname [-e filename] [-f filename] [-p password] [-t timestamp] [-l filename] [-v] <file[list]> \n";
240    print "Options:\n";
241    print "\t -e filename\t\t\tFile which contains a list of files which don't have to be signed.\n";
242    print "\t -f pfx_filename\t\t\"Personal Information Exchange\" file.\n";
243    print "\t -p password\t\t\tPassword for \"Personal Information Exchange\" file.\n";
244    print "\t -t timestamp\t\t\tTimestamp URL e.g. \"http://timestamp.verisign.com/scripts/timstamp.dll\"\n";
245    print "\t -l log_filename\t\tFile for logging.\n";
246    print "\t -v\t\t\t\tVerbose.\n";
247}   ##usage
248
249
250
251
252