1: #!/usr/bin/perl -w
2: ##############################################################################
3: ## -*-perl-*-
4: ##
5: ## ydecode - A better, faster yEnc decoder.
6: ##
7: ## REVISION HISTORY
8: ##
9: ## 1.0 2002/02/27 Initial release.
10: ## 1.1 2002/03/02 Fixed miscellaneous translation bugs.
11: ## 1.2 2002/03/12 Code around utf8 badness by working at the byte level.
12: ## 1.3 2002/11/05 Precompute mapping for a slight speedup (robobunny).
13: ##############################################################################
14:
15: package Convert::yEnc;
16:
17: use strict;
18: use String::CRC32;
19: use Exporter;
20: use vars qw(@ISA @EXPORT_OK);
21: @ISA = qw(Exporter);
22: @EXPORT_OK = qw(decode);
23:
24: sub decode($)
25: {
26: my $fh = shift;
27:
28: my $size;
29: my $name;
30: my $part;
31: my $offset;
32: my $pSize;
33: my $decoded;
34: my @ymap = map { ($_-42+256)%256 } (0..255);
35:
36: my $decoding = 0;
37: binmode($fh);
38: while(<$fh>) {
39: chomp;
40: if (!$decoding) {
41: if (/^=ybegin/) {
42: if (/ size=(\d+)/) {
43: $size = $1;
44: }
45: else {
46: die "size field in ybegin is mandatory.\n";
47: }
48:
49: if (/ part=(\d+)/) {
50: $part = $1;
51: }
52: else {
53: undef $part;
54: }
55:
56: if (/ name=(.*)$/) {
57: $name = $1;
58: $name =~ s/\s+$//g;
59: print "Found attachment $name of size $size.\n";
60: }
61: else {
62: die "name field in ybegin is mandatory.\n";
63: }
64:
65: if (defined $part) {
66: my $line = <$fh>;
67: chomp $line;
68: $line =~ s/\s+$//g;
69: if ($line =~ /^=ypart/) {
70: if ($line =~ / begin=(\d+)/) {
71: $offset = $1 - 1;
72: }
73: else {
74: print "Part $part has no begin field - ignoring.\n";
75: undef $part;
76: }
77: if ($line =~ / end=(\d+)/) {
78: $pSize = $1 - $offset;
79: }
80: else {
81: print "Part $part has no end field - ignoring.\n";
82: undef $part;
83: }
84: print "File $name is multipart.\n" if ($part == 1);
85: print "Processing part $part.\n";
86: }
87: else {
88: print "ybegin with part= field not followed"
89: ." by ypart=. Treating as a single part.\n";
90: undef $part;
91: }
92: }
93:
94: undef $decoded;
95: $decoding = 1 if (defined $size);
96: }
97: }
98: else {
99: if (/^=yend/) {
100: $decoding = 0;
101:
102: my $endSize;
103: if (/size=(\d+)/) {
104: $endSize = $1;
105: }
106: else {
107: print "Size is mandatory in yend, ignoring encoded stuff.\n";
108: next;
109: }
110:
111: my $crc;
112: if (defined $part) {
113: if (/ pcrc32=([0-9a-f]+)/i) {
114: $crc = $1;
115: }
116: }
117: else {
118: if (/ crc32=([0-9a-f]+)/i) {
119: $crc = $1;
120: }
121: }
122:
123: if (defined $crc) {
124: my $realCRC = crc32($decoded);
125: if (hex($crc) != $realCRC) {
126: print "CRCs mismatch. Expected ", $crc;
127: print " got ", sprintf("%x", $realCRC), ".\n";
128: next;
129: }
130: }
131:
132: my $decodedSize = length($decoded);
133: if (defined $part) {
134: if ($decodedSize != $pSize) {
135: die "Size mismatch. Expected $pSize, got $decodedSize.\n";
136: }
137:
138: print "Writing part $part to $name...";
139: if ($part == 1) {
140: open(FH,"> $name") or die "Can't write to file $name\n";
141: }
142: else {
143: open(FH,"+< $name") or die "Can't append to $name\n";
144: }
145: binmode(FH);
146: seek(FH, $offset, 0);
147: print FH $decoded;
148: close(FH);
149: print "done.\n";
150: }
151: else {
152: if ($endSize != $size) {
153: die "begin/end size mismatch. Expected $size, got $endSize.\n";
154: }
155: if ($decodedSize != $endSize) {
156: die "Size mismatch. Expected $endSize, got $decodedSize.\n";
157: }
158:
159: print "Writing $name...";
160: open(FH, "> $name") or die "Can't write to file $name\n";
161: binmode(FH);
162: print FH $decoded;
163: close(FH);
164: print "done.\n";
165: }
166: }
167: else {
168: my $line = $_;
169:
170: # Remove extraneous trailing 0x0d's, if possible.
171: $line =~ s/\x0d$//;
172:
173: # Work with bytes, to protect against utf8 hardship.
174: my @bytes = unpack("C*", $line);
175: my @uline;
176: foreach (my $i=0; $i<scalar(@bytes); $i++) {
177: if ($bytes[$i] == ord('=')) {
178: $i++;
179: $bytes[$i] -= 64;
180: }
181: push @uline, $ymap[$bytes[$i]];
182: }
183: $decoded .= pack("C*", @uline);
184: }
185: }
186: }
187: }
188:
189: 1;
190:
191: package main;
192:
193: use strict;
194: use Getopt::Std;
195:
196: my %opt;
197:
198: my $error = !getopts('w', \%opt);
199: if ($error) {
200: print << "EOU";
201:
202: Usage: ydecode [-w] < file
203:
204: where
205: -w Print out warranty information
206:
207: EOU
208: }
209: elsif ($opt{'w'}) {
210: print << "EOW";
211: ------------------------------------------------------------------------------
212: BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
213: FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
214: OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
215: PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
216: OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
217: MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
218: TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
219: PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
220: REPAIR OR CORRECTION.
221:
222: IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
223: WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
224: REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
225: INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
226: OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
227: TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
228: YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
229: PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
230: POSSIBILITY OF SUCH DAMAGES.
231: EOW
232: }
233: else {
234: Convert::yEnc::decode(\*STDIN);
235: }
236:
237: __END__
238: =pod
239:
240: =head1 NAME
241:
242: ydecode - A better, faster yEnc decoder.
243:
244: =head1 SYNOPSIS
245:
246: ydecode [-w] < file
247: -w Print out warranty information
248:
249: =head1 DESCRIPTION
250:
251: C<ydecode> decodes yEnc data from the standard input and
252: writes out the embedded file(s) to the current working directory.
253:
254: =head1 EXAMPLES
255:
256: ydecode < file
257:
258: cat 00000005.ntx | ydecode
259:
260:
261: =head1 INSTALLATION
262:
263: You will need the following module(s), if you don't already have them:
264:
265: String::CRC32
266:
267: Getopt::Std
268:
269: =head1 AUTHOR
270:
271: Gerard Lanois <gerard@lanois.com>
272:
273: Courtesy of Gerard's Perl Page, http://home.san.rr.com/lanois/perl/
274:
275: =head1 CREDITS
276:
277: This is based on yencdecoder.pl, yenc format decoder - v1.0 - 20020224
278: by Hellstorm a.k.a. Jaume Bacardit Peñarroya) - <helly@he11storm.net>
279:
280: =head1 LICENSE
281:
282: ydecode - Copyright (C) 2002 Gerard Lanois <gerard@lanois.com>
283:
284: This program is free software; you can redistribute it and/or modify
285: it under the terms of the GNU General Public License as published by
286: the Free Software Foundation; either version 2 of the License, or
287: (at your option) any later version.
288:
289: This program is distributed in the hope that it will be useful,
290: but WITHOUT ANY WARRANTY; without even the implied warranty of
291: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
292: GNU General Public License for more details.
293:
294: You should have received a copy of the GNU General Public License
295: along with this program; if not, write to the Free Software
296: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
297:
298: =cut
299:
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: ydecode - A better, faster yEnc decoder.
by Kanji (Parson) on Feb 28, 2002 at 03:18 UTC | |
by perldoc (Scribe) on Feb 28, 2002 at 18:20 UTC | |
by perldoc (Scribe) on Mar 01, 2002 at 06:17 UTC | |
by pne (Novice) on Mar 01, 2002 at 10:33 UTC | |
by perldoc (Scribe) on Mar 02, 2002 at 19:38 UTC | |
|
Re: ydecode - A better, faster yEnc decoder.
by robobunny (Friar) on Jul 16, 2002 at 12:51 UTC | |
by perldoc (Scribe) on Nov 05, 2002 at 20:57 UTC | |
by Anonymous Monk on Nov 07, 2002 at 01:16 UTC | |
|
Re: ydecode - A better, faster yEnc decoder.
by perldoc (Scribe) on Mar 02, 2002 at 19:37 UTC |