home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/perl
- # unpack.pl -- unpack files
- # SCCS Status : @(#)@ unpack 2.4
- # Author : Johan Vromans
- # Created On : Oct 2 21:33:00 1989
- # Last Modified By: Johan Vromans
- # Last Modified On: Sun May 3 17:37:22 1992
- # Update Count : 5
- # Status : Going steady
-
- # Unpack a set of files sent by the mail server with a tiny bit
- # of error detection.
- #
- # Usage: save all the parts in one big file (in the correct order),
- # say "foo", and then execute:
- #
- # perl unpack.pl foo
- #
- # Note: if the filename contains a path, all subdirectories should
- # exist!
- # Multiple files in one input stream are allowed: e.g:
- #
- #------ begin of INDEX -- ascii -- complete ------
- #------ end of INDEX -- ascii -- complete ------
- #------ begin of zoo.TZ -- btoa encoded -- part 1 of 2 ------
- #------ end of zoo.TZ -- btoa encoded -- part 1 of 2 ------
- #------ begin of zoo.TZ -- btoa encoded -- part 2 of 2 ------
- #------ end of zoo.TZ -- btoa encoded -- part 2 of 2 ------
- #
- #
- ################ configuration section ################
- #
- # Where to find these...
- #
- $atob = "atob"; # Ascii -> Binary
- $uudecode = "uudecode"; # UU
- $xxdecode = "xxdecode"; # XX
- $uud = "uud"; # Dumas' uue/uud programs.
- #
- ################ end of configuration section ################
-
- &init;
-
- while ( $line = <> ) {
-
- if ( $line =~ /^------ begin of (.+) -- (.+) -- (.+) ------/ ) {
- print STDERR $line;
-
- # If a filename is known, it must be the same.
- if ( $file ) {
- if ( $file != $1 ) {
- &errmsg ("Filename mismatch");
- }
- }
- else {
- $file = $1;
- }
-
- # If an encoding is known, it must be the same.
- if ( $encoding ) {
- if ( $encoding != $2 ) {
- &errmsg ("Encoding mismatch");
- }
- }
- else {
- # Determine encoding and build command.
- $encoding = $2;
- if ( $encoding eq "uuencoded" ) {
- $cmd = "|$uudecode";
- }
- elsif ( $encoding eq "xxencoded" ) {
- $cmd = "|$xxdecode";
- }
- elsif ( $encoding eq "btoa encoded" ) {
- $cmd = "|$atob > $file";
- }
- elsif ( $encoding eq "uue-encoded" ) {
- $cmd = "|$uud - ";
- }
- else {
- $cmd = ">$file";
- }
- }
-
- # If a 'parts' section is known, it must match.
- # A bit more complex ...
- $tparts = $3;
- if ( $parts ) {
- if ( $tparts =~ /part (\d+) of (\d+)/ ) {
-
- $thispart++; # Increment part number and check.
- if ( $thispart != $1 ) {
- &errmsg ("Sequence mismatch");
- }
-
- # Total number must match also.
- if ( $numparts ) {
- if ( $numparts != $2 ) {
- &errmsg ("Numparts mismatch");
- }
- }
- else {
- $numparts = $2;
- }
- }
- elsif ( $parts ne $tparts ) {
- &errmsg ("Parts mismatch");
- }
- }
- else {
-
- # No 'parts' known yet.
- $parts = $tparts;
- if ( $tparts =~ /part (\d+) of (\d+)/ ) {
- $thispart = $1;
- # Should be first part.
- if ( $thispart != 1 ) {
- &errmsg ("Sequence mismatch");
- }
- $numparts = $2;
- }
- else {
- $numparts = $thispart = 1;
- }
- }
-
- # If we have a file open, enable copying.
- if ( $fileok ) {
- $copy = 1;
- }
- elsif ( open (OUTFILE, $cmd) ) {
- $fileok = 1;
- $copy = 1;
- }
- else {
- &errmsg ("Cannot create $cmd");
- }
-
- # Matching end header to look for.
- $trailer = "------ end " . substr ($line, 13, length($line)-13);
-
- }
- elsif ( $line =~ /^------ end of (.+) -- (.+) -- (.+) ------/ ) {
-
- print STDERR $line;
-
- # Check that the header matches.
- if ( $line ne $trailer ) {
- &errmsg ("Header/trailer mismatch");
- }
-
- # Wrap up if this was the last part.
- &wrapup if $thispart == $numparts;
-
- # Stop copying.
- $copy = 0;
- }
- else {
- if ( $copy ) {
- print OUTFILE $line;
- }
- }
- }
-
- if ( $numparts && ( $thispart != $numparts )) {
- &errmsg ("Only $thispart of $numparts parts found");
- }
-
- if ( $fileok) {
- &errmsg ("Unterminated section") if $?;
- }
-
- ################ Subroutines ################
-
- sub init {
- $encoding = "";
- $parts = "";
- $numparts = "";
- $file = "";
- $copy = 0;
- $thispart = 0;
- $fileok = "";
- }
-
- sub wrapup {
- close (OUTFILE);
- &errmsg ("Output close error [$?]") if $?;
- &init;
- }
-
- sub errmsg {
- print STDERR ($my_name, ": ", pop(@_), " at input line $..\n");
- exit 1;
- }
-