PAR-1.016/0000755000175000017500000000000013470566717012343 5ustar roderichroderichPAR-1.016/Makefile.PL0000644000175000017500000000504713332605573014312 0ustar roderichroderich#!/usr/bin/perl use strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile1( NAME => 'PAR', VERSION_FROM => 'lib/PAR.pm', ABSTRACT_FROM => 'lib/PAR.pm', LICENSE => 'perl_5', AUTHOR => [ 'Audrey Tang ' ], MIN_PERL_VERSION => '5.008001', PREREQ_PM => { 'File::Temp' => '0.05', 'Compress::Zlib' => ($^O eq 'MSWin32') ? '1.16' : '1.30', 'Archive::Zip' => '1.00', 'PAR::Dist' => '0.32', 'AutoLoader' => '5.66_02', 'Digest::SHA' => '5.45', }, TEST_REQUIRES => { 'Test::More' => 0, }, META_MERGE => { 'meta-spec' => { version => 2 }, resources => { repository => { type => 'git', url => 'git://github.com/rschupp/PAR.git', web => 'https://github.com/rschupp/PAR', }, MailingList => 'mailto:par@perl.org', bugtracker => { web => 'https://rt.cpan.org/Dist/Display.html?Queue=PAR' }, }, }, clean => { FILES => 't/hello.par' }, ); sub MY::postamble { return <<'...'; pure_all :: t/hello.par t/hello.par: $(PERL) t/gen-hello-par.pl ... } sub WriteMakefile1 { #Compatibility code for old versions of EU::MM. Written by Alexandr Ciornii, version 2. Added by eumm-upgrade. my %params=@_; my $eumm_version=$ExtUtils::MakeMaker::VERSION; $eumm_version=eval $eumm_version; die "EXTRA_META is deprecated" if exists $params{EXTRA_META}; die "License not specified" if not exists $params{LICENSE}; if ($params{AUTHOR} and ref($params{AUTHOR}) eq 'ARRAY' and $eumm_version < 6.5705) { $params{META_ADD}->{author}=$params{AUTHOR}; $params{AUTHOR}=join(', ',@{$params{AUTHOR}}); } if ($params{TEST_REQUIRES} and $eumm_version < 6.64) { $params{BUILD_REQUIRES}={ %{$params{BUILD_REQUIRES} || {}} , %{$params{TEST_REQUIRES}} }; delete $params{TEST_REQUIRES}; } if ($params{BUILD_REQUIRES} and $eumm_version < 6.5503) { #EUMM 6.5502 has problems with BUILD_REQUIRES $params{PREREQ_PM}={ %{$params{PREREQ_PM} || {}} , %{$params{BUILD_REQUIRES}} }; delete $params{BUILD_REQUIRES}; } delete $params{CONFIGURE_REQUIRES} if $eumm_version < 6.52; delete $params{MIN_PERL_VERSION} if $eumm_version < 6.48; delete $params{META_MERGE} if $eumm_version < 6.46; delete $params{META_ADD} if $eumm_version < 6.46; delete $params{LICENSE} if $eumm_version < 6.31; WriteMakefile(%params); } PAR-1.016/t/0000755000175000017500000000000013470566717012606 5ustar roderichroderichPAR-1.016/t/gen-hello-par.pl0000644000175000017500000000031213016353133015547 0ustar roderichroderichuse strict; use warnings; use Archive::Zip qw( :ERROR_CODES ); my $zip = Archive::Zip->new(); exit($zip->addTree("t/data", "") == AZ_OK && $zip->writeToFileNamed("t/hello.par") == AZ_OK ? 0 : 1); PAR-1.016/t/00-pod.t0000644000175000017500000000040413014631602013744 0ustar roderichroderichuse strict; use warnings; use Test::More; plan skip_all => "Set environment variable PERL_TEST_POD=1 to test POD" if not $ENV{PERL_TEST_POD}; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); PAR-1.016/t/01-basic.t0000644000175000017500000000153013014631602014245 0ustar roderichroderich#!/usr/bin/perl use strict; use warnings; use Test::More tests => 8; use File::Spec; use File::Path; use File::Temp (); BEGIN { $ENV{PAR_TMPDIR} = File::Temp::tempdir(TMPDIR => 1, CLEANUP => 1); $ENV{PAR_CLEAN} = 1; } ok( `"$^X" -Mblib -MPAR -It/hello -MHello -e Hello::hello`, "Hello, world!\n", ); ok( `"$^X" -Mblib -MPAR t/hello.par hello.pl`, "Hello, world!\nGoodbye, world!\n", ); ok( `"$^X" -Mblib -MPAR t/hello.par nostrict.pl`, "No Strict!\n", ); ok( `"$^X" -Mblib -MPAR t/hello.par data.pl`, "Data section\nData reflection\n", ); require PAR; PAR->import('t/hello.par'); ok( PAR::read_file('script/hello.pl'), qr/Hello::hello/, ); ok( my $zip = PAR::par_handle('t/hello.par') ); ok( my $member = $zip->memberNamed('lib/Hello.pm') ); ok( $member->contents, qr/package Hello/, ); __END__ PAR-1.016/t/40-par-hashref.t0000644000175000017500000000206613016353522015400 0ustar roderichroderich#!/usr/bin/perl -w use strict; use Test::More tests => 7; use File::Spec; use File::Temp (); use FindBin; use vars qw/@INC %INC/; $ENV{PAR_TMPDIR} = File::Temp::tempdir(TMPDIR => 1, CLEANUP => 1); unshift @INC, ($FindBin::Bin); use_ok('PAR'); my $par = File::Spec->catfile($FindBin::Bin, 'hello.par'); ok(-f $par, 'PAR file for testing exists.'); eval "use PAR { file => '$par'};"; warn $@ if $@; ok(!$@, "use PAR {file =>...} threw error"); require Hello; my $res = Hello::hello(); ok($res, "Hello from PAR returned true"); delete $INC{'Hello.pm'}; %PAR::PAR_INC = %PAR::PAR_INC = (); @PAR::PAR_INC = @PAR::PAR_INC = (); @PAR::PAR_INC_LATE = @PAR::PAR_INC_LATE = (); eval "use PAR { file => '$par', fallback => 1 };"; warn $@ if $@; ok(!$@, "use PAR {file=>...,fallback=>1} threw error"); undef *Hello::hello; require Hello; $res = Hello::hello(); ok(!$res, "Hello from filesys returned false"); ok(eval("require Data; 1;"), 'fallback works'); print PAR->import({run => 'hello', file => $par}); ok(0, 'should not be reached if hello from par file is executed!'); PAR-1.016/t/Hello.pm0000644000175000017500000000016213014631602014162 0ustar roderichroderichpackage Hello; # This package (and file) is used by 40-par-hashref.t use strict; sub hello { return(); } 1; PAR-1.016/t/60-cleanup.t0000644000175000017500000000121413014631602014617 0ustar roderichroderich#!/usr/bin/perl use strict; use warnings; # This test is supposed to make sure that # the /tmp/par-$USER/temp-$$ directories get cleaned up when # in CLEAN mode. use File::Temp (); use Test::More tests => 5; BEGIN { $ENV{PAR_TMPDIR} = File::Temp::tempdir(TMPDIR => 1, CLEANUP => 1); $ENV{PAR_CLEAN} = 1; delete $ENV{PAR_TEMP}; } ok(!defined $ENV{PAR_TEMP}, "No PAR_TEMP to start with"); require PAR; PAR->import(); ok(1, "Loaded PAR"); ok(defined $ENV{PAR_TEMP}, "Loading PAR defined PAR_TEMP"); ok(-d $ENV{PAR_TEMP}, "Loading PAR created the PAR_TEMP directory"); my $partemp = $ENV{PAR_TEMP}; END { ok(not -d $partemp); } __END__ PAR-1.016/t/50-autoloaderfix.t0000644000175000017500000000115213014631602016036 0ustar roderichroderich#!/usr/bin/perl # Problem doesn't manifest if Test::More is in effect? # What the hell? use File::Temp (); BEGIN { $ENV{PAR_TMPDIR} = File::Temp::tempdir(TMPDIR => 1, CLEANUP => 1); } $|=1; print "1..1\n"; use PAR; package Bar; use AutoLoader 'AUTOLOAD'; # Can't use strict and warnings because in case of the # erroneous recursion, we'll require ourselves and get a # "subroutine redefined" error which doesn't matter. sub new { return bless {} => $_[0]; } package main; $INC{"Bar.pm"} = $0; # <-- { my $p = Bar->new(); } # <-- looping while looking for Bar::DESTROY print "ok 1 - AutoLoader works\n"; PAR-1.016/t/data/0000755000175000017500000000000013470566717013517 5ustar roderichroderichPAR-1.016/t/data/script/0000755000175000017500000000000013470566717015023 5ustar roderichroderichPAR-1.016/t/data/script/nostrict.pl0000644000175000017500000000006407557047642017225 0ustar roderichroderich#!/usr/bin/perl ${'a'} = "No Strict!\n"; print $a; PAR-1.016/t/data/script/data.pl0000644000175000017500000000012207554264244016260 0ustar roderichroderich#!/usr/bin/perl use Data; Data::data(); print ; __DATA__ Data reflection PAR-1.016/t/data/script/hello.pl0000644000175000017500000000011007554264250016444 0ustar roderichroderich#!/usr/bin/perl use Hello; Hello::hello(); print "Goodbye, world!\n"; PAR-1.016/t/data/lib/0000755000175000017500000000000013470566717014265 5ustar roderichroderichPAR-1.016/t/data/lib/Hello.pm0000644000175000017500000000011307554064226015653 0ustar roderichroderichpackage Hello; use strict; sub hello { print "Hello, world!\n"; } 1; PAR-1.016/t/data/lib/Data.pm0000644000175000017500000000012407554264205015462 0ustar roderichroderichpackage Data; use strict; sub data { print ; } 1; __DATA__ Data section PAR-1.016/inc/0000755000175000017500000000000013470566717013114 5ustar roderichroderichPAR-1.016/inc/Module/0000755000175000017500000000000013470566717014341 5ustar roderichroderichPAR-1.016/inc/Module/Install/0000755000175000017500000000000013470566717015747 5ustar roderichroderichPAR-1.016/META.yml0000644000175000017500000000151513470566717013616 0ustar roderichroderich--- abstract: 'Perl Archive Toolkit' author: - 'Audrey Tang ' build_requires: ExtUtils::MakeMaker: '0' Test::More: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: PAR no_index: directory: - t - inc requires: Archive::Zip: '1.00' AutoLoader: 5.66_02 Compress::Zlib: '1.30' Digest::SHA: '5.45' File::Temp: '0.05' PAR::Dist: '0.32' perl: '5.008001' resources: MailingList: mailto:par@perl.org bugtracker: https://rt.cpan.org/Dist/Display.html?Queue=PAR repository: git://github.com/rschupp/PAR.git version: '1.016' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' PAR-1.016/MANIFEST0000644000175000017500000000140713470566717013476 0ustar roderichroderichAUTHORS Changes inc/Module/Install.pm inc/Module/Install/Base.pm inc/Module/Install/Can.pm inc/Module/Install/Fetch.pm inc/Module/Install/Makefile.pm inc/Module/Install/Metadata.pm inc/Module/Install/Win32.pm inc/Module/Install/WriteAll.pm lib/PAR.pm lib/PAR/Environment.pod lib/PAR/FAQ.pod lib/PAR/Heavy.pm lib/PAR/SetupProgname.pm lib/PAR/SetupTemp.pm lib/PAR/Tutorial.pod LICENSE Makefile.PL MANIFEST This list of files MANIFEST.SKIP META.yml PAR-1.012.tar.gz README t/00-pod.t t/01-basic.t t/40-par-hashref.t t/50-autoloaderfix.t t/60-cleanup.t t/data/lib/Data.pm t/data/lib/Hello.pm t/data/script/data.pl t/data/script/hello.pl t/data/script/nostrict.pl t/gen-hello-par.pl t/Hello.pm META.json Module JSON meta-data (added by MakeMaker) PAR-1.016/LICENSE0000644000175000017500000004415013014631602013330 0ustar roderichroderichCopyright 2002-2010 by Audrey Tang . Copyright 2006-2010 by Steffen Mueller . This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- Copyright 2002-2010 by Audrey Tang . Copyright 2006-2010 by Steffen Mueller . This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- Copyright 2002-2010 by Audrey Tang . Copyright 2006-2010 by Steffen Mueller . This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End PAR-1.016/MANIFEST.SKIP0000644000175000017500000000024113105571303014214 0ustar roderichroderich#defaults ^\..*\.sw.$ ^MANIFEST.bak$ ^Makefile$ ^Makefile.old$ ^blib/ ^pm_to_blib ^blibdirs \B\.git\b ^\.gitignore \B\.svn\b ^MYMETA\. ^typescript$ ^t/hello.par PAR-1.016/AUTHORS0000644000175000017500000000741513014631602013376 0ustar roderichroderichHere is a list of people and their CPAN id, extracted from the Changes file and the mailing list archives. These people have either submitted patches or suggestions, or their bug reports or comments have inspired the appropriate patches. Note that this list applies to both PAR and the now separate PAR-Packer distribution. Corrections, additions, deletions welcome: Abe Timmerman (ABELTJE) Abhijit Menon-Sen (AMS) Adam Kennedy (ADAMK) Alan Stewart Alan Teague Alasdair Allan (AALLAN) Alexey Borzenkov Alvin Belden Andrew Lee Andy Balaam Andy Lester (PETDANCE) Antti Lankila Arthur Bergman (ABERGMAN) Ask Bjoern Hansen (ABH) Barrie Slaymaker (RBS) Barry Jaspan Bill Atkins (BATKINS) Brad Elliott Brigitte Jellinek Bruce Winter Chia-Liang Kao (CLKAO) Chip Salzenberg (CHIPS) Chris Dolan (CDOLAN) Chris Williams Christian Schiefer Clayton O'Neill (CMO) Corey Goldberg Cosimo Streppone (COSIMO) D. Menzel Daniel Cohen-Laroque Daniel Shane (DSHANE) Darek Adamkiewicz (DADAMK) David Dyck David Romano Doug Gruber Doug Miles Edward S. Peschko Edward Wildgoose Eric Paulson Eric Wilhelm Gaal Yahas (GAAL) Gabor Szabo (SZABGAB) Gerald Richter (GRICHTER) Germain Garand (GGARAND) Glenn Mabbutt H. Wade Minter Henrique Dias (HDIAS) Hirosi Taguti Iain Cass Iain Truskett (SPOON) Ilya Zakharevich (ILYAZ) Indy Singh Ivan Kudryavtsev James Muir Jan Dubois (JDB) Jeff Goff (JGOFF) Jerrad Pierce Jerry Veldhuis Jesse Schoch Jesse Vincent (JESSE) Jody Belka (KNEW) Johan Lindstroem (JOHANL) Johannes Lode John McMahon John Siracusa (JSIRACUSA) Jonathan Leffler (JOHNL) Joseph Landman Jouke Visser (JOUKE) Karl Forner Kieran J Broadfoot Lindsay Morris Luc Willems Malcolm Nooning Marcus Ramberg (MRAMBERG) Mark Dootson (MDOOTSON) Mark Shelor (MSHELOR) Markus Jansen Martin Fabiani Martin Hosken (MHOSKEN) Matt Sergeant (MSERGEANT) Matthew Andersen Matthew Braid (MDBGRIZ) Matthew Riedel Mattia Barbon (MBARBON) Michael Goldberger Michael Schilli (MSCHILLI) Mike Campbell Mike Stok (MIKESTOK) Morbus Iff Murat Uenalan (MUENALAN) Nadim Ibn Hamouda El Khemir (NKH) Nathan Byrd (NBYRD) Ned Konz (NEDKONZ) Nicholas Clark (NWCLARK) Nicolas FROMENT Niko Tyni Nomota KIM Paritosh Tyagi Paul Miller Peter Klewinghaus Patrice Parmentier Patrick Whitney Phil Sallee Piotr Martyniuk PodMaster (PODMASTER) Rafael Garcia-Suarez (RGARCIA) Randal L. Schwartz (MERLYN) Randy Carpenter Randy W. Sims (RANDYS) Reini Urban Richard Soderberg (RSOD) Rick Fitzsimmons Rob Casey (ROBAU) Robert Allerstorfer Robert Creager (RCREAGER) Robert Wyrick Roderich Schupp (RSCHUPP) Rong-En Fan Ryan Briones Sascha Wuestemann Scott Stanton Sim Lim Hai Simon Andrews Simon Cozens (SIMON) Sisyphus Steffen Mueller (SMUELLER) Stephen Pick Steve Hay (SHAY) Steven Mackenzie Thomas Loo (TLOO) Thomas Rush Tim Conrow Tina Mueller (TINITA) Tom Pollard Tommy Butler Ton Hospel (THOSPEL) TP Diffenbach Uri Guttman (URI) Vincent Ladeuil Vladimir Yu. Tereshchenko PAR-1.016/META.json0000644000175000017500000000302513470566717013764 0ustar roderichroderich{ "abstract" : "Perl Archive Toolkit", "author" : [ "Audrey Tang " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "PAR", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Archive::Zip" : "1.00", "AutoLoader" : "5.66_02", "Compress::Zlib" : "1.30", "Digest::SHA" : "5.45", "File::Temp" : "0.05", "PAR::Dist" : "0.32", "perl" : "5.008001" } }, "test" : { "requires" : { "Test::More" : "0" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://rt.cpan.org/Dist/Display.html?Queue=PAR" }, "repository" : { "type" : "git", "url" : "git://github.com/rschupp/PAR.git", "web" : "https://github.com/rschupp/PAR" }, "x_MailingList" : "mailto:par@perl.org" }, "version" : "1.016", "x_serialization_backend" : "JSON::PP version 2.97001" } PAR-1.016/lib/0000755000175000017500000000000013470566717013111 5ustar roderichroderichPAR-1.016/lib/PAR/0000755000175000017500000000000013470566717013533 5ustar roderichroderichPAR-1.016/lib/PAR/SetupProgname.pm0000644000175000017500000000417613017067350016654 0ustar roderichroderichpackage PAR::SetupProgname; $PAR::SetupProgname::VERSION = '1.002'; use 5.006; use strict; use warnings; use Config (); =head1 NAME PAR::SetupProgname - Setup $ENV{PAR_PROGNAME} =head1 SYNOPSIS PAR guts, beware. Check L =head1 DESCRIPTION Routines to setup the C environment variable. Read the C manual. The C subroutine sets up the C environment variable =cut # for PAR internal use only! our $Progname = $ENV{PAR_PROGNAME} || $0; # same code lives in PAR::Packer's par.pl! sub set_progname { require File::Spec; if (defined $ENV{PAR_PROGNAME} and $ENV{PAR_PROGNAME} =~ /(.+)/) { $Progname = $1; } $Progname = $0 if not defined $Progname; if (( () = File::Spec->splitdir($Progname) ) > 1 or !$ENV{PAR_PROGNAME}) { if (open my $fh, $Progname) { return if -s $fh; } if (-s "$Progname$Config::Config{_exe}") { $Progname .= $Config::Config{_exe}; return; } } foreach my $dir (split /\Q$Config::Config{path_sep}\E/, $ENV{PATH}) { next if exists $ENV{PAR_TEMP} and $dir eq $ENV{PAR_TEMP}; my $name = File::Spec->catfile($dir, "$Progname$Config::Config{_exe}"); if (-s $name) { $Progname = $name; last } $name = File::Spec->catfile($dir, "$Progname"); if (-s $name) { $Progname = $name; last } } } 1; __END__ =head1 SEE ALSO L, L =head1 AUTHORS Audrey Tang Ecpan@audreyt.orgE, Steffen Mueller Esmueller@cpan.orgE You can write to the mailing list at Epar@perl.orgE, or send an empty mail to Epar-subscribe@perl.orgE to participate in the discussion. Please submit bug reports to Ebug-par@rt.cpan.orgE. If you need support, however, joining the Epar@perl.orgE mailing list is preferred. =head1 COPYRIGHT Copyright 2002-2010 by Audrey Tang Ecpan@audreyt.orgE. Copyright 2006-2010 by Steffen Mueller Esmueller@cpan.orgE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F. =cut PAR-1.016/lib/PAR/Environment.pod0000644000175000017500000002007113346237246016535 0ustar roderichroderich=head1 NAME PAR::Environment - Index and reference of PAR environment variables =head1 DESCRIPTION PAR uses various environment variables both during the building process of executables or PAR archives and the I of them. Since the wealth of combinations and settings might confuse one or the other (like me), this document is intended to document all environment variables which PAR uses. Wherever I want to refer to the C<$ENV{FOO}> environment hash entry, I will usually talk about the C variable for brevity. =head1 INDEX OF ENVIRONMENT VARIABLES B For each variable, there should be a description what it contains, when it can be expected to exist (and contain meaningful information), when it is sensible to define it yourself, and what effect this has. Of course, the description may use examples. =head2 PAR_0 If the running program is run from within a PAR archive or pp-produced executable, this variable contains the name of the extracted program (i.e. .pl file). This is useful of you want to open the source code file of the running program. For example, if you package a file F into F and run F with this command par.pl foo.par bar.pl then the C variable will contain something like C where C is your username and C is the PAR cache directory (C). The name of the PAR cache directory can take a number of different forms, so use C if you want to find the extracted program's .pl file -- attempting to construct the name yourself requires complex logic that has already produced the value in C. This works the same for executable binaries (F<.exe>, ...). If you are looking for the name and path of the pp-ed binary file, please refer to the C variable. =head2 PAR_CLEAN Users should set C instead. Recreated from C and the value of C<-C> from the YAML file by the PAR loader, and used within loader to control the initial behavior of extraction, and the final behavior of cleanup. The user can reference C in the application to determine which of these behaviors is being used for this run of the application. =head2 PAR_DEBUG Users should set C instead. If this variable is set to a true value and F is run, verbose output is sent to STDOUT or the logging filehandle. This is overridden by the C<-q> option to F, for steps after argument parsing occurs. This currently only influences F. Whether this is the intended behaviour remains to be verified. =head2 PAR_GLOBAL_CLEAN Setting C alters the behavior of par applications which see that environment variable at launch. C overrides the C<-C> option. Settings of 0 and 1 are supported. 0 corresponds to not using C<-C> on the pp command line; 1 corresponds to using C<-C> on the pp command line. C is ignored if C is set, yet it controls the form of C when C is not set. =head2 PAR_GLOBAL_DEBUG The PAR loader becomes more verbose when C is set. Setting C guarantees that C will be set internally, initially. See C for more details. =head2 PAR_GLOBAL_TEMP Contributes to the calculation of C, and is further explained there. =head2 PAR_GLOBAL_TMPDIR Contributes to the calculation of C, and is further explained there. =head2 PAR_INITIALIZED This environment variable is for internal use by the PAR binary loader only. Documented only to avoid surprises if spawned applications expect to see a value initialized by the user. =head2 PAR_PROGNAME C is set to the fully-qualified path name of the executable program. On Windows, this is reliably obtained from the C API. On other OSes, if the C runtime is given a qualified path name, it is used, or the unqualified file name given is qualified by walking the path. This is reasonably reliable given normal program spawning conventions, but cannot be guaranteed to be correct in all circumstances. =head2 PAR_APP_REUSE Strictly internal. Skip this section if you're not a PAR developer. The variable shouldn't ever be exposed to user code and packaged applications should not depend on it being set or not. If an application has been packaged with the C<--reusable> option, the bootstrapping code will set this environment variable to the name of the program that is to be run instead of the packaged program. The F loader script fetches the file name, deletes the environment variable, and then runs the given program. =head2 PAR_RUN This environment variable was set during constructions of C objects (usually during F runs only) by versions of PAR up to 0.957. Since PAR 0.958, this variable is unused. =head2 PAR_SPAWNED This variable is used internally by the F binary loader to signal the child process that it's the child. You should not rely on this variable outside of the PAR binary loader code. For a slightly more detailed discussion, please refer to the F documentation file in the PAR source distribution which was contributed by Alan Stewart. Documented only to avoid surprises if spawned applications expect to see a value initialized by the user. =head2 PAR_TEMP Users should set C instead. C is calculated from a variety of other variables. See the C section in the pod for PAR.pm for a complete description of how the calculation proceeds. C, once calculated, is used as the location where PAR stores its extracted, temporary file cache. =head2 PAR_TMPDIR Contributes to the calculation of C, and is further explained there. Users should set C instead. =head2 PAR_VERBATIM The C variable controls the way Perl code is packaged into a PAR archive or binary executable. If it is set to a true value during the packaging process, modules (and scripts) are B passed through the default C filter which removes all POD documentation from the code. Note that the C filter is still applied. The C<-F> option to the F tool overrides the C setting. That means if you set C but specify C<-F PodStrip> on the C command line, the C filter will be applied. C is not used by the PAR application. =head2 PAR_VERBOSE Setting this environment variable to a positive integer has the same effect as using the C<-verbose> switch to F. =head2 PP_OPTS During a F run, the contents of the C variable are treated as if they were part of the command line. In newer versions of PAR, you can also write options to a file and execute F as follows to read the options from the file: pp @FILENAME That can, of course, be combined with other command line arguments to F or the C variable. =head2 TMP, TEMP, TMPDIR, TEMPDIR Please refer to C. =head1 SEE ALSO L, L, L L, L, L L for details on PAR distributions. =head1 AUTHORS Steffen Mueller Esmueller@cpan.orgE You can write to the mailing list at Epar@perl.orgE, or send an empty mail to Epar-subscribe@perl.orgE to participate in the discussion. Please submit bug reports to Ebug-par@rt.cpan.orgE. If you need support, however, joining the Epar@perl.orgE mailing list is preferred. =head1 COPYRIGHT PAR: Copyright 2003-2010 by Audrey Tang, Ecpan@audreyt.orgE. This document: Copyright 2006-2010 by Steffen Mueller, Esmueller@cpan.orgE Some information has been taken from Alan Stewart's extra documentation in the F folder of the PAR distribution. This program or documentation is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F. =cut PAR-1.016/lib/PAR/SetupTemp.pm0000644000175000017500000001121713065010727016002 0ustar roderichroderichpackage PAR::SetupTemp; $PAR::SetupTemp::VERSION = '1.002'; use 5.006; use strict; use warnings; use Fcntl ':mode'; use PAR::SetupProgname; =head1 NAME PAR::SetupTemp - Setup $ENV{PAR_TEMP} =head1 SYNOPSIS PAR guts, beware. Check L =head1 DESCRIPTION Routines to setup the C environment variable. The documentation of how the temporary directories are handled is currently scattered across the C manual and the C manual. The C subroutine sets up the C environment variable. =cut # for PAR internal use only! our $PARTemp; # name of the canary file our $Canary = "_CANARY_.txt"; # how much to "date back" the canary file (in seconds) our $CanaryDateBack = 24 * 3600; # 1 day # The C version of this code appears in myldr/mktmpdir.c # This code also lives in PAR::Packer's par.pl as _set_par_temp! sub set_par_temp_env { PAR::SetupProgname::set_progname() unless defined $PAR::SetupProgname::Progname; if (defined $ENV{PAR_TEMP} and $ENV{PAR_TEMP} =~ /(.+)/) { $PARTemp = $1; return; } my $stmpdir = _get_par_user_tempdir(); die "unable to create cache directory" unless $stmpdir; require File::Spec; if (!$ENV{PAR_CLEAN} and my $mtime = (stat($PAR::SetupProgname::Progname))[9]) { require Digest::SHA; my $ctx = Digest::SHA->new(1); if ($ctx and open(my $fh, "<$PAR::SetupProgname::Progname")) { binmode($fh); $ctx->addfile($fh); close($fh); } $stmpdir = File::Spec->catdir( $stmpdir, "cache-" . ( $ctx ? $ctx->hexdigest : $mtime ) ); } else { $ENV{PAR_CLEAN} = 1; $stmpdir = File::Spec->catdir($stmpdir, "temp-$$"); } $ENV{PAR_TEMP} = $stmpdir; mkdir $stmpdir, 0700; $PARTemp = $1 if defined $ENV{PAR_TEMP} and $ENV{PAR_TEMP} =~ /(.+)/; } # Find any digester # Used in PAR::Repository::Client! sub _get_digester { my $ctx = eval { require Digest::SHA; Digest::SHA->new(1) } || eval { require Digest::SHA1; Digest::SHA1->new } || eval { require Digest::MD5; Digest::MD5->new }; return $ctx; } # find the per-user temporary directory (eg /tmp/par-$USER) # Used in PAR::Repository::Client! sub _get_par_user_tempdir { my $username = _find_username(); my $temp_path; foreach my $path ( (map $ENV{$_}, qw( PAR_TMPDIR TMPDIR TEMPDIR TEMP TMP )), qw( C:\\TEMP /tmp . ) ) { next unless defined $path and -d $path and -w $path; # create a temp directory that is unique per user # NOTE: $username may be in an unspecified charset/encoding; # use a name that hopefully works for all of them; # also avoid problems with platform-specific meta characters in the name $temp_path = File::Spec->catdir($path, "par-".unpack("H*", $username)); ($temp_path) = $temp_path =~ /^(.*)$/s; unless (mkdir($temp_path, 0700) || $!{EEXIST}) { warn "creation of private subdirectory $temp_path failed (errno=$!)"; return; } unless ($^O eq 'MSWin32') { my @st; unless (@st = lstat($temp_path)) { warn "stat of private subdirectory $temp_path failed (errno=$!)"; return; } if (!S_ISDIR($st[2]) || $st[4] != $< || ($st[2] & 0777) != 0700 ) { warn "private subdirectory $temp_path is unsafe (please remove it and retry your operation)"; return; } } last; } return $temp_path; } # tries hard to find out the name of the current user sub _find_username { my $username; my $pwuid; # does not work everywhere: eval {($pwuid) = getpwuid($>) if defined $>;}; if ( defined(&Win32::LoginName) ) { $username = &Win32::LoginName; } elsif (defined $pwuid) { $username = $pwuid; } else { $username = $ENV{USERNAME} || $ENV{USER} || 'SYSTEM'; } return $username; } 1; __END__ =head1 SEE ALSO L, L =head1 AUTHORS Audrey Tang Ecpan@audreyt.orgE, Steffen Mueller Esmueller@cpan.orgE You can write to the mailing list at Epar@perl.orgE, or send an empty mail to Epar-subscribe@perl.orgE to participate in the discussion. Please submit bug reports to Ebug-par@rt.cpan.orgE. If you need support, however, joining the Epar@perl.orgE mailing list is preferred. =head1 COPYRIGHT Copyright 2002-2010 by Audrey Tang Ecpan@audreyt.orgE. Copyright 2006-2010 by Steffen Mueller Esmueller@cpan.orgE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F. =cut PAR-1.016/lib/PAR/Heavy.pm0000644000175000017500000001404713441535417015142 0ustar roderichroderichpackage PAR::Heavy; $PAR::Heavy::VERSION = '0.12'; =head1 NAME PAR::Heavy - PAR guts =head1 SYNOPSIS (internal use only) =head1 DESCRIPTION No user-serviceable parts inside. =cut ######################################################################## # Dynamic inclusion of XS modules # NOTE: Don't "use" any module here, esp. one that is an XS module or # whose "use" could cause the loading of an XS module thru its dependencies. # enable debug/trace messages from DynaLoader perl code my $dl_debug = $ENV{PERL_DL_DEBUG} || 0; my ($bootstrap, $dl_findfile); # Caches for code references my ($cache_key); # The current file to find my $is_insensitive_fs = ( -s $0 and (-s lc($0) || -1) == (-s uc($0) || -1) and (-s lc($0) || -1) == -s $0 ); # Adds pre-hooks to Dynaloader's key methods sub _init_dynaloader { return if $bootstrap; return unless eval { require DynaLoader; DynaLoader::dl_findfile(); 1 }; print STDERR "PAR::Heavy: pre-hooks to Dynaloader's key methods\n" if $dl_debug; $bootstrap = \&DynaLoader::bootstrap; $dl_findfile = \&DynaLoader::dl_findfile; local $^W; *{'DynaLoader::dl_expandspec'} = sub { return }; *{'DynaLoader::bootstrap'} = \&_bootstrap; *{'DynaLoader::dl_findfile'} = \&_dl_findfile; } # Return the cached location of .dll inside PAR first, if possible. sub _dl_findfile { print STDERR "PAR::Heavy::_dl_findfile($cache_key)\n" if $dl_debug; if (exists $FullCache{$cache_key}) { print STDERR " found in FullCache as $FullCache{$cache_key}\n" if $dl_debug; return $FullCache{$cache_key}; } if ($is_insensitive_fs) { # We have a case-insensitive filesystem... my ($key) = grep { lc($_) eq lc($cache_key) } keys %FullCache; if (defined $key) { print STDERR " found case-insensitively in FullCache as $FullCache{$key}\n" if $dl_debug; return $FullCache{$key}; } } print STDERR " fall back to DynaLoader::dl_findfile\n" if $dl_debug; return $dl_findfile->(@_); } # Find and extract .dll from PAR files for a given dynamic module. sub _bootstrap { my (@args) = @_; my ($module) = $args[0] or return; my @modparts = split(/::/, $module); my $modfname = $modparts[-1]; $modfname = &DynaLoader::mod2fname(\@modparts) if defined &DynaLoader::mod2fname; if (($^O eq 'NetWare') && (length($modfname) > 8)) { $modfname = substr($modfname, 0, 8); } my $modpname = join((($^O eq 'MacOS') ? ':' : '/'), @modparts); my $file = $cache_key = "auto/$modpname/$modfname.$DynaLoader::dl_dlext"; if ($FullCache{$file}) { # TODO: understand local $DynaLoader::do_expand = 1; return $bootstrap->(@args); } my $member; # First, try to find things in the preferentially loaded PARs: $member = PAR::_find_par_internals([@PAR::PAR_INC], undef, $file, 1) if defined &PAR::_find_par_internals; # If that failed to find the dll, let DynaLoader (try or) throw an error unless ($member) { my $filename = eval { $bootstrap->(@args) }; return $filename if not $@ and defined $filename; # Now try the fallback pars $member = PAR::_find_par_internals([@PAR::PAR_INC_LAST], undef, $file, 1) if defined &PAR::_find_par_internals; # If that fails, let dynaloader have another go JUST to throw an error # While this may seem wasteful, nothing really matters once we fail to # load shared libraries! unless ($member) { return $bootstrap->(@args); } } $FullCache{$file} = _dl_extract($member); # Now extract all associated shared objs in the same auto/ dir # XXX: shouldn't this also set $FullCache{...} for those files? my $first = $member->fileName; my $path_pattern = $first; $path_pattern =~ s{[^/]*$}{}; if ($PAR::LastAccessedPAR) { foreach my $member ( $PAR::LastAccessedPAR->members ) { next if $member->isDirectory; my $name = $member->fileName; next if $name eq $first; next unless $name =~ m{^/?\Q$path_pattern\E\/[^/]*\.\Q$DynaLoader::dl_dlext\E[^/]*$}; $name =~ s{.*/}{}; _dl_extract($member, $name); } } local $DynaLoader::do_expand = 1; return $bootstrap->(@args); } sub _dl_extract { my ($member, $name) = @_; $name ||= $member->crc32String . ".$DynaLoader::dl_dlext"; my $filename = File::Spec->catfile($ENV{PAR_TEMP} || File::Spec->tmpdir, $name); ($filename) = $filename =~ /^([\x20-\xff]+)$/; return $filename if -e $filename && -s _ == $member->uncompressedSize; # $filename doesn't exist or hasn't been completely extracted: # extract it under a temporary name that isn't likely to be used # by concurrent processes doing the same my $tempname = "$filename.$$"; $member->extractToFileNamed($tempname) == Archive::Zip::AZ_OK() or die "Can't extract archive member ".$member->fileName." to $tempname: $!"; # now that we have a "good" copy in $tempname, rename it to $filename; # if this fails (e.g. some OSes won't let you delete DLLs that are # in use), but $filename exists, we assume that $filename is also # "good": remove $tempname and return $filename unless (rename($tempname, $filename)) { -e $filename or die "can't rename $tempname to $filename: $!"; unlink($tempname); } return $filename; } 1; =head1 SEE ALSO L =head1 AUTHORS Audrey Tang Ecpan@audreyt.orgE You can write to the mailing list at Epar@perl.orgE, or send an empty mail to Epar-subscribe@perl.orgE to participate in the discussion. Please submit bug reports to Ebug-par@rt.cpan.orgE. =head1 COPYRIGHT Copyright 2002-2010 by Audrey Tang Ecpan@audreyt.orgE. Copyright 2006-2010 by Steffen Mueller Esmueller@cpan.orgE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F. =cut PAR-1.016/lib/PAR/Tutorial.pod0000644000175000017500000005207413017067371016037 0ustar roderichroderich=head1 NAME PAR::Tutorial - Cross-Platform Packaging and Deployment with PAR =head1 SYNOPSIS This is a tutorial on PAR, first appeared at the 7th Perl Conference. The HTML version of this tutorial is available online as L =head1 DESCRIPTION =head2 On Deploying Perl Applications % sshnuke.pl 10.2.2.2 -rootpw="Z1ON0101" Perl v5.6.1 required--this is only v5.6.0, stopped at sshnuke.pl line 1. BEGIN failed--compilation aborted at sshnuke.pl line 1. =over 4 =item * Q: "Help! I can't run your program!" =item * A1: Install Perl & C =over 4 =item * How do we know which modules are needed? =item * New versions of CPAN modules may break C =back =item * A2: Install Perl & C =over 4 =item * Possibly overwriting existing modules; not cross-platform at all =back =item * A3: Use the executable generated by C =over 4 =item * Impossible to debug; C usually does not work anyway =back =back =head2 PAR, the Perl Archive Toolkit =over 4 =item * Do what JAR (Java Archive) does for Perl =over 4 =item * Aggregates modules, scripts and other files into a Zip file =item * Easy to generate, update and extract =item * Version consistency: solves forward-compatibility problems =item * Developed by community: C =back =item * PAR files can be packed into self-contained scripts =over 4 =item * Automatically scans perl script for dependencies =item * Bundles all necessary 3rd-party modules with it =item * Requires only core Perl to run on the target machine =item * PAR also comes with C, the Perl Packager: % pp -o sshnuke.exe sshnuke.pl # stand-alone executable! =back =back =head2 Simple Packaging =over 4 =item * PAR files are just Zip files with modules in it =item * Any Zip tools can generate them: % zip foo.par Hello.pm World.pm # pack two modules % zip -r bar.par lib/ # grab all modules in lib/ =item * To load modules from PAR files: use PAR; use lib "foo.par"; # the .par part is optional use Hello; =item * This also works: use PAR "/home/mylibs/*.par"; # put all of them into @INC use Hello; =back =head2 PAR Loaders =over 4 =item * Use C to run files inside a PAR archive: % par.pl foo.par # looks for 'main.pl' by default % par.pl foo.par test.pl # runs script/test.pl in foo.par =item * Same thing, with the stand-alone C or C: % parl foo.par # no perl or PAR.pm needed! % parl foo.par test.pl # ditto =item * The PAR loader can prepend itself to a PAR file: =over 4 =item * C<-b> bundles non-core modules needed by C: % par.pl -b -O./foo.pl foo.par # self-contained script =item * C<-B> bundles core modules in addition to C<-b>: % parl -B -O./foo.exe foo.par # self-contained binary =back =back =head2 Dependency Scanning =over 4 =item * Recursively scan dependencies with C: % scandeps.pl sshnuke.pl # Legend: [C]ore [X]ternal [S]ubmodule [?]NotOnCPAN 'Crypt::SSLeay' => '0', # X # 'Net::HTTP' => '0', # # 'Crypt::SSLeay::X509' => '0', # S # Crypt::SSLeay 'Net::HTTP::Methods' => '0', # S # Net::HTTP 'Compress::Zlib' => '0', # X # Net::HTTP::Methods =item * Scan an one-liner, list all involved files: % scandeps.pl -V -e "use Dynaloader;" ... # auto/DynaLoader/dl_findfile.al [autoload] # auto/DynaLoader/extralibs.ld [autoload] # auto/File/Glob/Glob.bs [data] # auto/File/Glob/Glob.so [shared] ... =back =head2 Perl Packager: C =over 4 =item * Combines scanning, zipping and loader-embedding: % pp -o out.exe src.pl # self-contained .exe % out.exe # runs anywhere on the same OS =item * Bundle additional modules: % pp -o out.exe -M CGI src.pl # pack CGI + its dependencies, too =item * Pack one-liners: % pp -o out.exe -e 'print "Hi!"' # turns one-liner into executable =item * Generate PAR files instead of executables: % pp -p src.pl # makes 'source.par' % pp -B -p src.pl # include core modules =back =head2 How it works =over 4 =item * Command-line options are almost identical to C's =over 4 =item * Also supports C-style long options: % pp --gui --verbose --output=out.exe src.pl =back =item * Small initial overhead; no runtime overhead =item * Dependencies are POD-stripped before packing =item * Loads modules directly into memory on demand =item * Shared libraries (DLLs) are extracted with File::Temp =item * Works on Perl 5.6.0 or above =item * Tested on Win32 (VC++ and MinGW), FreeBSD, NetBSD, Linux, MacOSX, Cygwin, AIX, Solaris, HP-UX, Tru64... =back =head2 Aggregating multiple programs =over 4 =item * A common question: > I have used pp to make several standalone applications which work > great, the only problem is that for each executable that I make, I am > assuming the parl.exe is somehow bundled into the resulting exe. =item * The obvious workaround: You can ship parl.exe by itself, along with .par files built by "pp -p", and run those PAR files by associating them to parl.exe. =item * On platforms that have C, there is a better solution: % pp --output=a.out a.pl b.pl # two scripts in one! % ln a.out b.out # symlink also works % ./a.out # runs a.pl % ./b.out # runs b.pl =back =head2 Cross-platform Packages =over 4 =item * Of course, there is no cross-platform binary format =item * Pure-perl PAR packages are cross-platform by default =over 4 =item * However, XS modules are specific to Perl version and platform =item * Multiple versions of a XS module can co-exist in a PAR file =back =item * Suppose we need C on both Win32 and Finix: C:\> pp --multiarch --output=out.par src.pl ...copy src.pl and out.par to a Finix machine... % pp --multiarch --output=out.par src.pl =item * Now it works on both platforms: % parl out.par # runs src.pl % perl -MPAR=out.par -e '...' # uses modules inside out.par =back =head2 The Anatomy of a PAR file =over 4 =item * Modules can reside in several directories: / # casual packaging only /lib/ # standard location /arch/ # for creating from blib/ /i386-freebsd/ # i.e. $Config{archname} /5.8.0/ # i.e. Perl version number /5.8.0/i386-freebsd/ # combination of the two above =item * Scripts are stored in one of the two locations: / # casual packaging only /script/ # standard location =item * Shared libraries may be architecture- or perl-version-specific: /shlib/(5.8.0/)?(i386-freebsd/)? =item * PAR files may recursively contain other PAR files: /par/(5.8.0/)?(i386-freebsd/)? =back =head2 Special files =over 4 =item * MANIFEST =over 4 =item * Index of all files inside PAR =item * Can be parsed with C =back =item * META.yml =over 4 =item * Dependency, license, runtime options =item * Can be parsed with C =back =item * SIGNATURE =over 4 =item * OpenPGP-signed digital signature =item * Can be parsed and verified with C =back =back =head2 Advantages over perlcc, PerlApp and Perl2exe =over 4 =item * This is not meant to be a flame =over 4 =item * All three maintainers have contributed to PAR directly; I'm grateful =back =item * perlcc =over 4 =item * "The code generated in this way is not guaranteed to work... Use for production purposes is strongly discouraged." (from perldoc perlcc) =item * I is more like it =back =item * PerlApp / Perl2exe =over 4 =item * Expensive: Need to pay for each upgrade =item * Non-portable: Only available for limited platforms =item * Proprietary: Cannot extend its features or fix bugs =item * Obfuscated: Vendor and black-hats can see your code, but you can't =item * Inflexible: Does not work with existing Perl installations =back =back =head2 MANIFEST: Best viewed with Mozilla =over 4 =item * The URL of C inside C: jar:file:///home/autrijus/foo.par!/MANIFEST =item * Open it in a Gecko browser (e.g. Netscape 6+) with Javascript enabled: =item * No needed to unzip anything; just click on files to view them =back =head2 META.yml: Metadata galore =over 4 =item * Static, machine-readable distribution metadata =over 4 =item * Supported by C, C, C =back =item * A typical C-generated C looks like this: build_requires: {} conflicts: {} dist_name: out.par distribution_type: par dynamic_config: 0 generated_by: 'Perl Packager version 0.03' license: unknown par: clean: 0 signature: '' verbatim: 0 version: 0.68 =item * The C settings controls its runtime behavior =back =head2 SIGNATURE: Signing and verifying packages =over 4 =item * OpenPGP clear-signed manifest with SHA1 digests =over 4 =item * Supported by C, C and C =back =item * A typical C looks like this: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 SHA1 8a014cd6d0f6775552a01d1e6354a69eb6826046 AUTHORS ... -----BEGIN PGP SIGNATURE----- ... -----END PGP SIGNATURE----- =item * Use C and C to work with signatures: % pp -s -o foo.par bar.pl # make and sign foo.par from bar.pl % cpansign -s foo.par # sign this PAR file % cpansign -v foo.par # verify this PAR file =back =head2 Perl Servlets with Apache::PAR =over 4 =item * Framework for self-contained Web applications =over 4 =item * Similar to Java's "Web Application Archive" (WAR) files =item * Works with mod_perl 1.x or 2.x =back =item * A complete web application inside a C<.par> file =over 4 =item * Apache configuration, static files, Perl modules... =item * Supports Static, Registry and PerlRun handlers =item * Can also load all PARs under a directory =back =item * One additional special file: C Alias /myapp/cgi-perl/ ##PARFILE##/ Options +ExecCGI SetHandler perl-script PerlHandler Apache::PAR::Registry =back =head2 Hon Dah, A-par-che! =over 4 =item * First, make a C from an one-liner: # use the "web.conf" from the previous slide % pp -p -o hondah.par -e 'print "Hon Dah!\n"' \ --add web.conf % chmod a+x hondah.par =item * Add this to C, then restart apache: PerlModule Apache2 PerlAddVar PARInclude /home/autrijus/hondah.par PerlModule Apache::PAR =item * Test it out: % GET http://localhost/myapp/cgi-perl/main.pl Hon Dah! =item * Instant one-liner web application that works! =back =head2 On-demand library fetching =over 4 =item * With LWP installed, your can use remote PAR files: use PAR; use lib 'http://aut.dyndns.org/par/DBI-latest.par'; use DBI; # always up to date! =item * Modules are now cached under C<$ENV{PAR_GLOBAL_TEMP}> =item * Auto-updates with C =over 4 =item * Download only if modified =item * Safe for offline use after the first time =item * May use C to prevent DNS-spoofing =back =item * Makes large-scale deployment a breeze =over 4 =item * Upgrades from a central location =item * No installers needed =back =back =head2 Code Obfuscation =over 4 =item * Also known as I techniques =over 4 =item * It is I encryption =item * Offered by PerlApp, Perl2Exe, Stunnix... =back =item * Usually easy to defeat =over 4 =item * Take optree dump from memory, feed to C =item * If you just want to stop a casual C, "deflate" already works =back =item * PAR now supports pluggable I with C =over 4 =item * Bundled examples: Bleach, PodStrip and PatchContent =item * True encryption using C =item * Or even _product activation_ over the internet =back =item * Alternatively, just keep core logic in your server and use RPC =back =head2 Accessing packed files =over 4 =item * To get the host archive from a packed program: my $zip = PAR::par_handle($0); # an Archive::Zip object my $content = $zip->contents('MANIFEST'); =item * Same thing, but with C: my $content = PAR::read_file('MANIFEST'); =item * Loaded PAR files are stored in C<%PAR::LibCache>: use PAR '/home/mylibs/*.par'; while (my ($filename, $zip) = each %PAR::LibCache) { print "[$filename - MANIFEST]\n"; print $zip->contents('MANIFEST'); } =back =head2 Packing GUI applications =over 4 =item * GUI toolkits often need to link with shared libraries: # search for libncurses under library paths and pack it % pp -l ncurses curses_app.pl # same for Tk, Wx, Gtk, Qt... =item * Use C on Win32 to eliminate the console window: # pack 'src.pl' into a console-less 'out.exe' (Win32 only) % pp --gui -o out.exe src.pl =item * "Can't locate Foo/Widget/Bar.pm in @INC"? =over 4 =item * Some toolkits (notably Tk) autoloads modules without C or C =item * Hence C and C may fail to detect them =item * Tk problems mostly fixed by now, but other toolkits may still break =item * You can work around it with C or an explicit C =item * Or better, send a short test-case to C so we can fix it =back =back =head2 Precompiled CPAN distributions =over 4 =item * Installing XS extensions from CPAN was difficult =over 4 =item * Some platforms do not come with a compiler (Win32, MacOSX...) =item * Some headers or libraries may be missing =item * PAR.pm itself used to suffer from both problems =back =item * ...but not anymore -- C to the rescue! # same old Makefile.PL, with a few changes use inc::Module::Install; # was "use ExtUtils::MakeMaker;" WriteMakefile( ... ); # same as the original check_nmake(); # make sure the user have nmake par_base('AUTRIJUS'); # your CPAN ID or a URL fetch_par() unless can_cc(); # use precompiled PAR only if necessary =item * Users will not notice anything, except now it works =over 4 =item * Of course, you still need to type C and upload the precompiled package =item * PAR users can also install it directly with C =back =back =head2 Platform-specific Tips =over 4 =item * Win32 and other icon-savvy platforms =over 4 =item * Needs 3rd-party tools to add icons to C-generated executables =item * PE Header manipulation in Perl -- volunteers wanted! =back =item * Linux and other libc-based platforms =over 4 =item * Try to avoid running C on a bleeding-edge version of the OS =item * Older versions with an earlier libc won't work with new ones =back =item * Solaris and other zlib-lacking platforms (but not Win32) =over 4 =item * You need a static-linked C before installing PAR =item * In the future, PAR may depend on C instead =back =item * Any platform with limited bandwidth or disk space =over 4 =item * Use UPX to minimize the executable size =back =back =head2 Thank you! =over 4 =item * Additional resources =over 4 =item * Mailing list: C =item * Subscribe: Send a blank email to C =item * List archive: L =item * PAR::Intro: L =item * Apache::PAR: L =item * Module::Install: L =back =item * Any questions? =back =head2 Bonus Slides: PAR Internals =head2 Overview of PAR.pm's Implementation =over 4 =item * Here begins the scary part =over 4 =item * Grues, Dragons and Jabberwocks abound... =item * You are going to learn weird things about Perl internals =back =item * PAR invokes four areas of Perl arcana: =over 4 =item * @INC code references =item * On-the-fly source filtering =item * Overriding C to handle XS modules =item * Making self-bootstrapping binary executables =back =item * The first two only works on 5.6 or later =over 4 =item * DynaLoader and C<%INC> are there since Perl 5 was born =item * PAR currently needs 5.6, but a 5.005 port is possible =back =back =head2 Code References in @INC =over 4 =item * On 1999-07-19, Ken Fox submitted a patch to P5P =over 4 =item * To _enable using remote modules_ by putting hooks in @INC =item * It's accepted to come in Perl 5.6, but undocumented until 5.8 =item * Type C to read the nitty-gritty details =back =item * Coderefs in @INC may return a fh, or undef to 'pass': push @INC, sub { my ($coderef, $filename) = @_; # $coderef is \&my_sub open my $fh, "wget ftp://example.com/$filename |"; return $fh; # using remote modules, indeed! }; =item * Perl 5.8 let you open a file handle to a string, so we just use that: open my $fh, '<', \($zip->memberNamed($filename)->contents); return $fh; =item * But Perl 5.6 does not have that, and I don't want to use temp files... =back =head2 Source Filtering without Filter::* Modules =over 4 =item * ... Undocumented features to the rescue! =over 4 =item * It turns out that @INC hooks can return B values =item * The first is still the file handle =item * The second is a code reference for line-by-line source filtering! =back =item * This is how C works: # Force all modules used to use strict and warnings open my $fh, "<", $filename or return; my @lines = ("use strict; use warnings;\n", "#line 1 \"$full\"\n"); return ($fh, sub { return 0 unless @lines; push @lines, $_; $_ = shift @lines; return length $_; }); =back =head2 Source Filtering without Filter::* Modules (cont.) =over 4 =item * But we don't really have a filehandle for anything =item * Another undocumented feature saves the day! =item * We can actually omit the first return value altogether: # Return all contents line-by-line from the file inside PAR my @lines = split( /(?<=\n)/, $zip->memberNamed($filename)->contents ); return (sub { $_ = shift(@lines); return length $_; }); =back =head2 Overriding DynaLoader::bootstrap =over 4 =item * XS modules have dynamically loaded libraries =over 4 =item * They cannot be loaded as part of a zip file, so we extract them out =item * Must intercept DynaLoader's library-finding process =back =item * Module names are passed to C for XS loading =over 4 =item * During the process, it calls C to locate the file =item * So we install pre-hooks around both functions =back =item * Our C<_bootstrap> just checks if the library is in PARs =over 4 =item * If yes, extract it to a C temp file =over 4 =item * The file will be automatically cleaned up when the program ends =back =item * It then pass the arguments to the original C =item * Finally, our C intercepts known filenames and return it =back =back =head2 Anatomy of a Self-Contained PAR executable =over 4 =item * The par script ($0) itself =over 4 =item * May be in plain-text or native executable format =back =item * Any number of embedded files =over 4 =item * Typically used to bootstrap PAR's various dependencies =item * Each section begins with the magic string "FILE" =item * Length of filename in pack('N') format and the filename (auto/.../) =item * File length in pack('N') and the file's content (not compressed) =back =item * One PAR file =over 4 =item * Just a regular zip file with the magic string C<"PK\003\004"> =back =item * Ending section =over 4 =item * A pack('N') number of the total length of FILE and PAR sections =item * Finally, there must be a 8-bytes magic string: C<"\012PAR.pm\012"> =back =back =head2 Self-Bootstrapping Tricks =over 4 =item * All we can expect is a working perl interpreter =over 4 =item * The self-contained script *must not* use any modules at all =item * But to process PAR files, we need XS modules like Compress::Zlib =back =item * Answer: bundle all modules + libraries used by PAR.pm =over 4 =item * That's what the C section in the previous slide is for =item * Load modules to memory, and write object files to disk =item * Then use a local C<@INC> hook to load them on demand =back =item * Minimizing the amount of temporary files =over 4 =item * First, try to load PerlIO::scalar and File::Temp =item * Set up an END hook to unlink all temp files up to this point =item * Load other bundled files, and look in the compressed PAR section =item * This can be much easier with a pure-perl C; patches welcome! =back =back =head2 Thank you (again)! =over 4 =item * Any questions, I? =back =cut =head1 SEE ALSO L, L, L, L L, L L, L, L, L =head1 AUTHORS Audrey Tang Ecpan@audreyt.orgE You can write to the mailing list at Epar@perl.orgE, or send an empty mail to Epar-subscribe@perl.orgE to participate in the discussion. Please submit bug reports to Ebug-par@rt.cpan.orgE. =head1 COPYRIGHT Copyright 2003, 2004, 2005, 2006 by Audrey Tang Ecpan@audreyt.orgE. This document is free documentation; you can redistribute it and/or modify it under the same terms as Perl itself. See F. =cut PAR-1.016/lib/PAR/FAQ.pod0000644000175000017500000005153413017067310014634 0ustar roderichroderich=encoding utf8 =head1 NAME PAR::FAQ - Frequently Asked Questions about PAR =head1 SYNOPSIS This is the Frequently Asked Questions list for the Perl Archive Toolkit. This (included) FAQ list might be outdated. The Wiki version at the above URL is guaranteed to be up to date. =head1 DESCRIPTION =head2 Where is the Windows binary version? You can find windows binaries here: L There are three ways to install them. Sorted in order of preference: =head3 cpan Run the I command line tool that comes with Perl. In the I shell, type install PAR and wait for the script to download and extract PAR and its dependencies. If you have a C compiler installed, PAR will be built on your computer for your specific version of Perl. If you do not have a C compiler, the installer will look at the site referenced above for a compatible binary release and ask you whether you would like to install it. =head3 ppm If you are using ActivePerl from ActiveState, you can use the 'ppm' program that comes with the ActiveState Perl. Instructions can be found below. PAR is available from various PPM repositories and some packages are compatible with some versions of ActivePerl and not with others. There is an incomplete PAR-Win32 Binary Compatibility List at L There are at least three relevant PPM repositories: The default ActiveState one, the bribes repository which is used in the example below and Randy Kobes' repository at L. C:\> ppm3 # activestate was out of date compared to this one % rep add bribes http://www.bribes.org/perl/ppm # move it to first place on list of repositories % rep up bribes CPAN>upgrade -install PAR And finally, 'q' to quit and that's all :-) You have access to pp and so on... =head3 manual For reference, here's the old explanation of how to install it by hand: The file you need will be called PAR-X.XX-MSWin32-x86-multi-thread-Y.Y.Y.par where X.XX is the version of PAR you will use and Y.Y.Y is the version of Perl you have. Unzip this file (you may need to rename it to end with .zip instead of .par first) and copy all the files in the script directory into a directory in your PATH. Now you should be able to use PAR. =head2 Can PAR bundle all its prerequisites? I This entry needs serious attention. Yes and no. It would be possible to do this but it would also introduce a maintenance nightmare. A new version of PAR would have to be released whenever a new version of any of the dependencies came out. This is already painful with the included L. The original proposal which led to this FAQ entry considered the case where you want to install PAR without a working CPAN.pm/CPAN shell installation or without internet connectivity. By default, PAR will try to install its dependencies from CPAN using the CPAN.pm module. Given that you have a development machine with PAR installed and with a working CPAN.pm, it is reasonably simple to create one or more .par distributions of PAR's dependencies. Install L. Then you can create .par distributions (read: binaries installable with the pure-perl PAR::Dist on the same architecture) for the PAR dependencies as follows: mkdir par_files cpan2par --pattern PAR --follow --out par_files/ --merge --skip File::.* --skip Getopt::Std --skip Carp --skip Data::Dumper --skip Time::Local --skip 'Test\b.*' --skip Text::ParseWords --skip ExtUtils::.* --skip Getopt::Long --skip Text::Abbrev --skip DirHandle --skip Pod::.* (Line breaks inserted for readability.) What happens here? cpan2par uses the API of the CPAN.pm module to fetch the PAR distribution from CPAN, unpacks it, builds it, creates a .par archive from its compiled state and then does the same for any of its dependencies. And then for its dependencies dependencies and... You get the idea. This is what the --follow option does. We add a couple of --skip options to skip core modules which we need not include and any Test::* modules. The --merge option merges all of the .par distributions into the original PAR one. Voila! (Future versions of PAR::Dist::FromCPAN might include an option --skip-core which would skip any modules contained in the core distribution.) After this command worked its magic, you should have a single file PAR-VERSION-ARCHNAME-PERLVERSION.par in the subdirectory 'par_files/'. You can now install PAR and its non-core dependencies on any machine that has the architecture of your development system (and a binary compatible perl version) using L as follows: perl -MPAR::Dist -einstall_par Provided that you run the command from within the directory containing the aforementioned .par file (and no other .par file). Since you might not even have PAR::Dist on the target machine, you can do this simple hack to get a basic installer: perl -MPAR::Dist -e'open my $fh, "<", $INC{"PAR/Dist.pm"}; print <$fh>; print "\npackage main;\nPAR::Dist::install_par(\@ARGV ? shift(\@ARGV) : ());\n\n"' > installer.pl (Again: Line breaks inserted for readability.) This looks for your installed copy of PAR::Dist, reads it, writes it to STDOUT and appends two lines of code: "package main;" and a call to PAR::Dist::install_par. By default, it will install any (single) .par file in the current directory. If supplied with a file name as first argument, it will install the specified file. It should have no non-core dependencies! So shipping the generated PAR-....par file and the installer.pl file to the target machine and running "perl installer.pl" should just magically install PAR and its dependencies for you. Now, this whole trick works equally well for any other modules. In fact, if you have PAR on the target machine, you needn't even install the modules in the .par file in order to use them! You can just add "use PAR 'foo-bar.par';" to your code and any modules will be loaded from the .par file as necessary. ("perl -MPAR=foo-bar.par your_script.pl" works, too.) The documentation of the PAR module has details on this. Finally, note that you can install L on the target machines and subsequently use PAR 0.951 and later to automatically fetch any unfulfilled dependencies from a (remote or local) repository: use PAR { repository => 'http://my_local_secure_host/repository' }; or: use PAR { repository => 'file:///path/to/repository' }; Details, again, in the L documentation and in the L documentation. Answer from: Steffen Mueller, 16 August 2006 =head2 If I try to compile my wxGlade generated script, it doesn't run. What's wrong? I Is this still a problem? Comment out the line that starts with " unless (caller) ", and compile it again. Note that this is considered a bug; clearing the caller stack is a development in progress. =head2 I get a link error '/usr/bin/ld: cannot find -lperl' during the 'make' step of the installation on Debian. What's wrong? Install the C package. Note that Debian provides (usually up-to-date) packages of the modules in the PAR ecosystem: L, L, L and L; the corresponding packages are called C, C, C and C. =head2 I specify a .ico file with --icon for Win32, but the icon is still the black and white camel. What's wrong? Unlike Perl2EXE, which can use a standard 16-color bitmap as an application icon, PAR requires a true Windows icon file. Download a trial version of Microangelo and use that to create your .ico file. The latest Netpbm tools at L has ppmtowinicon, which can tack a pbm and convert it to a windows icon. It is open source and has win32 ports. Gimp for Windows can also create Windows icon files L. =head2 I added a directory to my PAR file using "zip -r" or winzip, and then generated an executable from this PAR file, and the executable failed to run (IO error: reading header signature :..). What's wrong? As pointed out by Alan Stewart, zip adds a directory entry for the new directory, and it causes the PAR executable to fail. Just use : zip -r -D hello.par my_dir/ or the Archive::Zip::addTree as follows : $zip->addTree( $root, $dest, sub { -f } ) =head2 On what platforms can I run PAR? On what platforms will the resulting executable run? Win32 (95/98/ME/NT4/2K/XP), FreeBSD, Linux, AIX, Solaris, Darwin and Cygwin. The resulting executable will run on any platforms that supports the binary format of the generating platform. =head2 How do I extract my script out of packed executable? In other words, "I did a `pp foo.pl' and I lost foo.pl, how do I get it back?". The answer is to just use unzip/winzip/winrar/whatever to decompress the executable, treating it like a normal Zip file. You may need to rename the executable into a .zip extension first. =head2 Can PAR completely hide my source code? Not completely, but possible to a degree. Starting from version 0.76, PAR supports an input filter mechanism, which can be used to implement source obfuscators (or even product activation schemes). But if you are looking for 100% bulletproof way of hiding source code, it is not possible with any language. Learning Perl, 3rd Edition has this answer to offer (quoted with permission from Randal Schwartz): If you're wishing for an opaque binary, though, we have to tell you that they don't exist. If someone can install and run your program, they can turn it back into source code. Granted, this won't necessarily be the same source that you started with, but it will be some kind of source code. The real way to keep your secret algorithm a secret is, alas, to apply the proper number of attorneys; they can write a license that says "you can do this with the code, but you can't do that. And if you break our rules, we've got the proper number of attorneys to ensure that you'll regret it." Other than that, I would point you at L. Be sure to read the CAVEATS and WARNINGS sections of the documentation. =head2 On Windows XP, pp crashes saying that "par.exe has encountered a problem" This is believed to be fixed by PAR 0.76_99. The following answer applies to PAR 0.76 and earlier: You may be able to escape this problem by setting some executables to Windows 95 compatibility mode. Specifically, find "parl.exe" (probably in "C:\perl\5.8.0\bin") using Windows Explorer, and right-click on it and choose "Properties". Choose the "Compatibility" tab and tick the box for "Run this program with compatibility mode for" and check that the dropdown shows "Windows 95". Then click OK. Now you can hopefully run pp as normal to generate an EXE. Before you can run the generated EXE, you'll need to set its compatibility mode too, in the same way as you did for parl.exe. This workaround is known not to work in all cases, and the developers are working on a solution to the problem. See these posts for more info: L, L, L, L =head2 Perl Tk tips On Windows XP start your script with use strict; use Encode::Unicode; use Tk; Some widgets use xbm bitmaps which don't get picked up by PAR. The error is: couldn't read bitmap file "": No such file or directory error reading bitmap file "" at Tk/Widget.pm line 205. at Tk/Widget.pm line 203 Fix is to find the missing xbm files (perl -V tells you where to start looking) and add them to the executable eg copy missing xbm files to script directory then: % pp --add cbxarrow.xbm --add arrowdownwin.xbm -o test test.pl =head2 Problem with Win32::Perms and Perms.DLL With a script my.pl using Win32::Perms, pp -o my.exe my.pl you may have: Can't locate loadable object for module Win32::Perms in @INC (@INC contains: CODE(0xb97eec) CODE(0xc8a99c) .) at ../blib/lib/PAR/Heavy.pm line 78 In fact the dll is Perms.DLL wit DLL in capital letters. That's the problem. The bootstrap function of PAR in the Dynaloader module fails looking for Perms.dll in the table of dlls which contains only Perms.DLL. And so the solution is just rename Perms.DLL in Perms.dll and do pp -o my.exe my.pl ... and everything goes right. =head2 Under Win32, a pp packed executable has trouble executing other perl scripts or pp packed executable I Is this still current? When running on a Win32 system, if a perl script is packed with pp and invokes another Perl script or pp packed executable, either with system() or backticks, the invoked program runs with the copy of perl5x.dll already loaded into memory. If the calling executable was packed with "pp -d", the perl5x.dll is the one from the installed perl bin directory. Otherwise, it is the one packed with the executable. The perl5x.dll from the bin dir knows the @INC paths for the installed libraries; the one in the executable does not. Because of this, a program packed without "-d" calling a program with packed with "-d" or calling perl.exe to run a plain Perl script may fail. This is a Win32 limitation. =head2 How can I make a .exe that runs with no console window under Windows? Use the --gui switch, ie % pp --gui -o file.exe file.pl I found that this is not documented on all versions of pp ... Some versions have a more complete doc than others when you type "pp -h" etc. (This should be reasonably documented now.) When searching for an answer to this myself, I found many references to using "exetype" ... it comes as a .bat with ActivePerl, or you can find an exetype.pl from several places. You run "exetype file.exe [WINDOWS|CONSOLE]". This worked, I think, but still did not achieve the desired result on my PAR executable. While the exe itself did not generate a console window, par.exe (which was invoked in my exe somewhere) DID generate a console window, with a titlebar saying "par.exe ", whereas before changing the console window title bar just displayed the path to my .exe. =head2 How can I change the icon of the generated .exe file under Windows? There is another not-completely-documented switch that only works on windows, --icon MyIcon.ico. So just use this: % pp --icon "c:\path to\MyIcon.ico" -o file.exe file.pl. (This should also be documented now?) =head2 The command line parameters (@ARGV) of a pp-ed binary called from another pp-ed binary are missing or broken. What the...? This was a bug in releases up to and including PAR-0.90. Please upgrade to PAR 0.91 or later and the problem will go away. =head2 I want to include a pp-ed binary in an RPM package. How can I make this work? The binary executables outputted by pp (on Linux) are not valid ELF binaries because it basically attaches a zip archive to the binary loader and does not modify the ELF headers to reflect that. When building an RPM archive, the validity of the ELF headers is checked by default. This can result in problems when packaging pp-ed binaries in RPM archives. Scott McBrien helped track down what can be done to get this to work: [I]t appears that the RPM archive that is generated gets a list of the MD5 sums for components of the executable file calculated by prelink. By disabling prelink, it fixed the problem; in my RPM .spec file: %define __prelink_undo_cmd %{nil} After quite some time, it seems like the smart folks at Redhat found the culprit. I'm glad *they* did, because I wouldn't have: It appears that we found a solution that works. It like the pp executables are already stripped, so we don't want rpm stripping them again, which, of course, renders them useless. In this case, we added the following lines to the spec file to keep rpm from running the strip process and not produce debuginfo packages: %define __spec_install_post : %define debug_package %{nil} Don't forget to add the ":" character to __spec_install_post as above or this won't work. Much praise to all who helped track this down! The discussion can be found in the following RT tickets: L and L. -- Steffen Mueller, 22 July 2006 =head2 How can I package Wx applications? Have a look at the separately maintained L module. -- Steffen Mueller, 3 July 2006 =head2 How can I package Catalyst web applications? Catalyst has some builtin PAR support. I found the following URL to be very helpful: L. -- Steffen Mueller, 21 July 2006 =head2 The resulting files are huge! How can I reduce the size of the output file? The executables generated by pp generally contain a copy of your Perl shared libraries, the Perl core modules and any module dependencies your packaged application may have. That is a lot. Sometimes, PAR packages too much. It adheres to the philosophy of rather making the application work than generating a streamlined executable. If you want to optimize this, you will have to do so by excluding specific modules. Chris Dolan's recent post to the PAR mailing list explains this well. Quoting Chris: (L) [...] I've found a few tricks that can help a lot: * If you know the target platform has Perl pre-installed (e.g. Mac OS X) then use the "--dependent" flag. This skips all of the core modules, yielding a much smaller executable. One significant caveat is moving to older systems. For example, Mac OS X 10.2 had Perl 5.6.0 which has 146 fewer core modules than Perl 5.8.6 which shipped with Mac OS X 10.4, and (even more significantly) is binary-incompatible with any extra XS modules added from CPAN. Other platforms can be even harder to predict. * Watch for modules that pull in lots of dependencies A good example is DBI. If your program uses DBI, then Module::ScanDeps pulls in ALL of the DBD::* modules (some of which are large) installed on your system, because it cannot realistically parse the DBI->connect() arguments which specify which database drivers are actually needed. In one of my MySQL-based applications, I use this invocation of PAR: pp -X DBD::SQLite -X DBD::CSV -X DBD::File -X DBD::Excel which saves quite a few bytes, because both DBD::SQLite and DBD::Excel have lots of CPAN dependencies. The actual list if DBD::* modules you need to exclude depends on your system. Here's a short command that will reveal all DBD::* modules on a unix-like system: perl -MModule::ScanDeps -le'print for map {"DBD/".$_->{name}} Module::ScanDeps::_glob_in_inc("DBD")' Another smaller example is SOAP::Transport::* where most installations only need SOAP::Transport::HTTP. [...] Similar techniques can be applied when a module makes use of L for plugins. Finally, there is a PAR filter available as a separate distribution on CPAN which compresses the source code as much as possible by first parsing it using PPI and then spitting out a reduced functional equivalent: L. -- Steffen Mueller, August 2006 =head2 How do I use Win32::GUI::SplashScreen with PAR? When using pp to package an application that uses Win32::GUI::SplashScreen, try adding the splashscreen bitmap manually as suggested in the Win32::GUI::SplashScreen docs: pp -a SPLASHFILE.bmp -o xxx.exe xxx.pl =head2 The Perl Packager scripts says that it can create executable that runs in same OS. Can I use it to create Win32 binary with linux machine? Or what should I use to create Win32 executable binary on linux from my script? It is not possible to create stand-alone binaries for different platform than what you are currently running on. This is a generally hard problem since you would have to cross-compile all XS modules and perl itself. Not nice. For example, if you would like to develop an application on Linux and ship it for both Linux/x86 and Win32/x86, it works well to set up a Virtual Machine with a Windows (XP or 2000 or whatever) and a Perl installation. On that machine, use PAR/pp to package your application for Win32. See also the question "On what platforms can I run PAR? On what platforms will the resulting executable run?". -- Steffen Mueller, 2 November 2006 =head1 SEE ALSO L, L =head1 AUTHORS Audrey Tang Ecpan@audreyt.orgE, Steffen Mueller Esmueller@cpan.orgE You can write to the mailing list at Epar@perl.orgE, or send an empty mail to Epar-subscribe@perl.orgE to participate in the discussion. Please submit bug reports to Ebug-par@rt.cpan.orgE. =head1 COPYRIGHT Copyright 2003-2008 by Audrey Tang Ecpan@audreyt.orgE. This document is free documentation; you can redistribute it and/or modify it under the same terms as Perl itself. See F. =cut PAR-1.016/lib/PAR.pm0000644000175000017500000012054013470565761014071 0ustar roderichroderichpackage PAR; $PAR::VERSION = '1.016'; use 5.006; use strict; use warnings; use Config '%Config'; use Carp qw/croak/; # If the 'prefork' module is available, we # register various run-time loaded modules with it. # That way, there is more shared memory in a forking # environment. BEGIN { if (eval 'require prefork') { prefork->import($_) for qw/ Archive::Zip File::Glob File::Spec File::Temp Fcntl LWP::Simple PAR::Heavy /; # not including Archive::Unzip::Burst which only makes sense # in the context of a PAR::Packer'ed executable anyway. } } use PAR::SetupProgname; use PAR::SetupTemp; =head1 NAME PAR - Perl Archive Toolkit =head1 SYNOPSIS (If you want to make an executable that contains all module, scripts and data files, please consult the L utility instead. L used to be part of the PAR distribution but is now shipped as part of the L distribution instead.) Following examples assume a F file in Zip format. To use F from F<./foo.par>: % perl -MPAR=./foo.par -MHello % perl -MPAR=./foo -MHello # the .par part is optional Same thing, but search F in C<@INC>: % perl -MPAR -Ifoo.par -MHello % perl -MPAR -Ifoo -MHello # ditto Following paths inside the PAR file are searched: /lib/ /arch/ /i386-freebsd/ # i.e. $Config{archname} /5.8.0/ # i.e. $Config{version} /5.8.0/i386-freebsd/ # both of the above / PAR files may also (recursively) contain other PAR files. All files under following paths will be considered as PAR files and searched as well: /par/i386-freebsd/ # i.e. $Config{archname} /par/5.8.0/ # i.e. $Config{version} /par/5.8.0/i386-freebsd/ # both of the above /par/ Run F