#!/usr/bin/perl -w # Creates self-extracting archives that use Perl to extract. # Will make directories on extraction, but parents of top-level # directories must exist and be writable. # # Outputs self-extracting archive to stdout. # Arguments that are directories will be recursed into. # # To make an archive: # perl separ.pl <fileOrDir> [...] > archive # # To unpack an archive: # perl archive # # Uses no external modules for decompression. # File format is: extractor program (Perl) at top, # __DATA__ tag, # multiple files, uuencoded. # There may be "mkdir" lines before files. # # By Ned Konz, perl@bike-nomad.com # encode() derived from Tom Christensen's PPT version of uuencode # decoder based on code by Nick Ing-Simmons and Tom Christiansen use strict; use File::Find; sub encode { my ( $source, $destination, $mode ) = @_; if ( $source eq '-' && -t STDIN ) { warn "$0: WARNING: reading from standard input\n"; } printf "begin %03o $destination\012", $mode || 0644; local *INPUT; open( INPUT, "< $source" ) || die "can't open $source: $!"; binmode(INPUT); my $block; print pack( "u", $block ) while read( INPUT, $block, 45 ); print "`\012"; print "end\012"; close(INPUT) || die "can't close $source: $!"; } # copy the extractor print $_ while (<DATA>); # now encode the files with relative path names $File::Find::dont_use_nlink = 1; for my $arg (@ARGV) { my $ignoreLength = length($arg) + 1; File::Find::find( { no_chdir => 1, wanted => sub { my $name = $File::Find::name; my $mode = $name eq '-' ? 0777 : ( stat($name) )[2]; if ( -d _ ) { $mode &= 0777; printf( "mkdir %03o %s\012", $mode || 0777, $name +); return; } encode( $name, $name, $mode & 0666 ); }, }, $arg ); } __DATA__ #!/usr/bin/perl use strict; # This is a self-extracting archive that requires Perl to extract. BEGIN { $/ = "\012" } while (<DATA>) { # attempt to be robust if someone edits this file in a different OS $_ =~ s/[\r\n]+$//s; next FILESPEC unless my ( $op, $mode, $file ) = /^(begin|mkdir)\s+(\d+)\s+(.*)/s +; if ( $op eq 'mkdir' ) { if ( !-d $file ) { print STDERR "making directory $file\n"; mkdir $file, 0777 or die "Can't make directory $file: $!\n"; } next; # filespec } my $foundEnd = 0; print STDERR "extracting file $file\n"; open( OUT, ">$file" ) or die "Can't create $file: $!\n"; binmode(OUT); while (<DATA>) { $_ =~ s/[\r\n]+$//s; if (/^end/) { $foundEnd++; last } next if /[a-z]/; next unless int( ( ( ( ord() - 32 ) & 077 ) + 2 ) / 3 ) == int( lengt +h() / 4 ); print OUT unpack( "u", $_ ) or die "can't write $file: $!"; } close(OUT) or die "can't close $file: $!"; chmod oct($mode), $file or die "can't chmod $file to $mode: $!\n"; $foundEnd or die "Missing end: $file may be truncated.\n"; } __DATA__

In reply to Self-extracting Perl archives by bikeNomad

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.