ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-UUlib/UUlib.pm
Revision: 1.11
Committed: Sun Oct 13 13:47:09 2002 UTC (21 years, 7 months ago) by root
Branch: MAIN
Changes since 1.10: +235 -152 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 package Convert::UUlib;
2    
3     use Carp;
4    
5     require Exporter;
6     require DynaLoader;
7     use AutoLoader;
8    
9 root 1.11 $VERSION = 0.214;
10 root 1.1
11     @ISA = qw(Exporter DynaLoader);
12    
13     @_consts = qw(
14     ACT_COPYING ACT_DECODING ACT_ENCODING ACT_IDLE ACT_SCANNING
15    
16     FILE_DECODED FILE_ERROR FILE_MISPART FILE_NOBEGIN FILE_NODATA
17     FILE_NOEND FILE_OK FILE_READ FILE_TMPFILE
18    
19     MSG_ERROR MSG_FATAL MSG_MESSAGE MSG_NOTE MSG_PANIC MSG_WARNING
20    
21     OPT_BRACKPOL OPT_DEBUG OPT_DESPERATE OPT_DUMBNESS OPT_ENCEXT
22     OPT_ERRNO OPT_FAST OPT_IGNMODE OPT_IGNREPLY OPT_OVERWRITE OPT_PREAMB
23     OPT_PROGRESS OPT_SAVEPATH OPT_TINYB64 OPT_USETEXT OPT_VERBOSE
24 root 1.8 OPT_VERSION OPT_REMOVE OPT_MOREMIME OPT_DOTDOT
25 root 1.1
26     RET_CANCEL RET_CONT RET_EXISTS RET_ILLVAL RET_IOERR RET_NODATA
27     RET_NOEND RET_NOMEM RET_OK RET_UNSUP
28    
29 root 1.11 B64_ENCODED BH_ENCODED PT_ENCODED QP_ENCODED
30 root 1.5 XX_ENCODED UU_ENCODED YENC_ENCODED
31 root 1.1 );
32    
33     @_funcs = qw(
34 root 1.6 Initialize CleanUp GetOption SetOption strerror SetMsgCallback
35     SetBusyCallback SetFileCallback SetFNameFilter SetFileNameCallback
36     FNameFilter LoadFile GetFileListItem RenameFile DecodeToTemp
37     RemoveTemp DecodeFile InfoFile Smerge QuickDecode EncodeMulti
38     EncodePartial EncodeToStream EncodeToFile E_PrepSingle
39     E_PrepPartial
40 root 1.1
41     straction strencoding strmsglevel
42     );
43    
44     @EXPORT = @_consts;
45     @EXPORT_OK = @_funcs;
46     %EXPORT_TAGS = (all => [@_consts,@_funcs], constants => \@_consts);
47    
48     bootstrap Convert::UUlib $VERSION;
49    
50     Initialize();
51    
52     # not when < 5.005_6x
53     # END { CleanUp() }
54    
55     for (@_consts) {
56     my $constant = constant($_);
57     *$_ = sub () { $constant };
58     }
59    
60     # action code -> string mapping
61     sub straction($) {
62     return 'copying' if $_[0] == &ACT_COPYING;
63     return 'decoding' if $_[0] == &ACT_DECODING;
64     return 'encoding' if $_[0] == &ACT_ENCODING;
65     return 'idle' if $_[0] == &ACT_IDLE;
66     return 'scanning' if $_[0] == &ACT_SCANNING;
67 root 1.5 'unknown';
68 root 1.1 }
69    
70     # encoding type -> string mapping
71     sub strencoding($) {
72 root 1.5 return 'uuencode' if $_[0] == &UU_ENCODED;
73 root 1.11 return 'base64' if $_[0] == &B64_ENCODED;
74 root 1.5 return 'yenc' if $_[0] == &YENC_ENCODED;
75 root 1.1 return 'binhex' if $_[0] == &BH_ENCODED;
76     return 'plaintext' if $_[0] == &PT_ENCODED;
77     return 'quoted-printable' if $_[0] == &QP_ENCODED;
78     return 'xxencode' if $_[0] == &XX_ENCODED;
79 root 1.5 'unknown';
80 root 1.1 }
81    
82     sub strmsglevel($) {
83     return 'message' if $_[0] == &MSG_MESSAGE;
84     return 'note' if $_[0] == &MSG_NOTE;
85     return 'warning' if $_[0] == &MSG_WARNING;
86     return 'error' if $_[0] == &MSG_ERROR;
87     return 'panic' if $_[0] == &MSG_PANIC;
88     return 'fatal' if $_[0] == &MSG_FATAL;
89 root 1.5 'unknown';
90 root 1.1 }
91    
92     1;
93     __END__
94    
95     =head1 NAME
96    
97     Convert::UUlib - Perl interface to the uulib library (a.k.a. uudeview/uuenview).
98    
99     =head1 SYNOPSIS
100    
101     use Convert::UUlib ':all';
102    
103 root 1.11 # read all the files named on the commandline and decode them
104 root 1.1 LoadFile($_) for @ARGV;
105     for($i=0; $uu=GetFileListItem($i); $i++) {
106     $uu->decode if $uu->state & FILE_OK;
107     }
108    
109 root 1.11 =head1 DESCRIPTION
110 root 1.1
111 root 1.11 Read the file doc/library.pdf from the distribution for in-depth
112     information about the C-library used in this interface, and the rest of
113     this document and especially the non-trivial decoder program at the end.
114    
115     =head1 EXPORTED CONSTANTS
116    
117     =head2 Action code constants
118    
119     ACT_IDLE we don't do anything
120     ACT_SCANNING scanning an input file
121     ACT_DECODING decoding into a temp file
122     ACT_COPYING copying temp to target
123     ACT_ENCODING encoding a file
124    
125     =head2 Message severity levels
126    
127     MSG_MESSAGE just a message, nothing important
128     MSG_NOTE something that should be noticed
129     MSG_WARNING important msg, processing continues
130     MSG_ERROR processing has been terminated
131     MSG_FATAL decoder cannot process further requests
132     MSG_PANIC recovery impossible, app must terminate
133    
134     =head2 Options
135    
136     OPT_VERSION version number MAJOR.MINORplPATCH (ro)
137     OPT_FAST assumes only one part per file
138     OPT_DUMBNESS switch off the program's intelligence
139     OPT_BRACKPOL give numbers in [] higher precendence
140     OPT_VERBOSE generate informative messages
141     OPT_DESPERATE try to decode incomplete files
142     OPT_IGNREPLY ignore RE:plies (off by default)
143     OPT_OVERWRITE whether it's OK to overwrite ex. files
144     OPT_SAVEPATH prefix to save-files on disk
145     OPT_IGNMODE ignore the original file mode
146     OPT_DEBUG print messages with FILE/LINE info
147     OPT_ERRNO get last error code for RET_IOERR (ro)
148     OPT_PROGRESS retrieve progress information
149     OPT_USETEXT handle text messages
150     OPT_PREAMB handle Mime preambles/epilogues
151     OPT_TINYB64 detect short B64 outside of Mime
152     OPT_ENCEXT extension for single-part encoded files
153     OPT_REMOVE remove input files after decoding
154     OPT_MOREMIME strict MIME adherence
155     OPT_DOTDOT .. unescaping has not yet been done on input files
156    
157     =head2 Result/Error codes
158    
159     RET_OK everything went fine
160     RET_IOERR I/O Error - examine errno
161     RET_NOMEM not enough memory
162     RET_ILLVAL illegal value for operation
163     RET_NODATA decoder didn't find any data
164     RET_NOEND encoded data wasn't ended properly
165     RET_UNSUP unsupported function (encoding)
166     RET_EXISTS file exists (decoding)
167     RET_CONT continue -- special from ScanPart
168     RET_CANCEL operation canceled
169    
170     =head2 File States
171    
172     This code is zero, i.e. "false":
173    
174     UUFILE_READ Read in, but not further processed
175    
176     The following state codes are ored together:
177    
178     FILE_MISPART Missing Part(s) detected
179     FILE_NOBEGIN No 'begin' found
180     FILE_NOEND No 'end' found
181     FILE_NODATA File does not contain valid uudata
182     FILE_OK All Parts found, ready to decode
183     FILE_ERROR Error while decoding
184     FILE_DECODED Successfully decoded
185     FILE_TMPFILE Temporary decoded file exists
186    
187     =head2 Encoding types
188    
189     UU_ENCODED UUencoded data
190     B64_ENCODED Mime-Base64 data
191     XX_ENCODED XXencoded data
192     BH_ENCODED Binhex encoded
193     PT_ENCODED Plain-Text encoded (MIME)
194     QP_ENCODED Quoted-Printable (MIME)
195     YENC_ENCODED yEnc encoded (non-MIME)
196 root 1.1
197 root 1.11 =head1 EXPORTED FUNCTIONS
198 root 1.1
199 root 1.11 =head2 Initializing and cleanup
200 root 1.1
201 root 1.11 Initialize is automatically called when the module is loaded and allocates
202     quite a bit of memory. CleanUp releases that again.
203 root 1.1
204     Initialize; # not normally necessary
205     CleanUp; # could be called at the end to release memory
206    
207 root 1.11 =head2 Setting and querying options
208 root 1.1
209     $option = GetOption OPT_xxx;
210     SetOption OPT_xxx, opt-value;
211    
212 root 1.11 =head2 Setting various callbacks
213 root 1.1
214     SetMsgCallback [callback-function];
215     SetBusyCallback [callback-function];
216     SetFileCallback [callback-function];
217     SetFNameFilter [callback-function];
218    
219 root 1.11 =head2 Call the currently selected FNameFilter
220 root 1.1
221     $file = FNameFilter $file;
222    
223 root 1.11 =head2 Loading sourcefiles, optionally fuzzy merge and start decoding
224 root 1.1
225     ($retval, $count) = LoadFile $fname, [$id, [$delflag]];
226     $retval = Smerge $pass;
227     $item = GetFileListItem $item_number;
228    
229 root 1.11 =head2 The procedural interface is undocumented, use the following methods instead
230 root 1.1
231     $retval = $item->rename($newname);
232     $retval = $item->decode_temp;
233     $retval = $item->remove_temp;
234     $retval = $item->decode([$target_path]);
235     $retval = $item->info(callback-function);
236    
237 root 1.11 =head2 Querying (and setting) item attributes
238 root 1.1
239     $state = $item->state;
240     $mode = $item->mode([newmode]);
241     $uudet = $item->uudet;
242     $size = $item->size;
243     $filename = $item->filename([newfilename});
244     $subfname = $item->subfname;
245     $mimeid = $item->mimeid;
246     $mimetype = $item->mimetype;
247     $binfile = $item->binfile;
248    
249 root 1.11 =head2 Totally undocumented but well tested ;)
250 root 1.1
251     $parts = $item->parts;
252    
253 root 1.11 =head2 Functions below not documented and not very well tested
254 root 1.1
255 root 1.11 QuickDecode
256     EncodeMulti
257     EncodePartial
258     EncodeToStream
259     EncodeToFile
260     E_PrepSingle
261     E_PrepPartial
262 root 1.6
263     =head2 EXTENSION FUNCTIONS
264    
265     Functions found in this module but not documented in the uulib documentation:
266    
267     =over 4
268    
269 root 1.11 =item $msg = straction ACT_xxx
270    
271     Return a human readable string representing the given action code.
272    
273     =item $msg = strerror RET_xxx
274    
275     Return a human readable string representing the given error code.
276    
277     =item $str = strencoding xxx_ENCODED
278    
279     Return the name of the encoding type as a string.
280    
281     =item $str = strmsglevel MSG_xxx
282    
283     Returns the message level as a string.
284    
285 root 1.6 =item SetFileNameCallback $cb
286    
287     Sets (or queries) the FileNameCallback, which is called whenever the
288     decoding library can't find a filename and wants to extract a filename
289     from the subject line of a posting. The callback will be called with
290     two arguments, the subject line and the current candidate for the
291     filename. The latter argument can be C<undef>, which means that no
292     filename could be found (and likely no one exists, so it is safe to also
293     return C<undef> in this case). If it doesn't return anything (not even
294     C<undef>!), then nothing happens, so this is a no-op callback:
295    
296     sub cb {
297     return ();
298     }
299    
300     If it returns C<undef>, then this indicates that no filename could be
301     found. In all other cases, the return value is taken to be the filename.
302    
303     This is a slightly more useful callback:
304    
305     sub cb {
306     return unless $_[1]; # skip "Re:"-plies et al.
307     my ($subject, $filename) = @_;
308     # if we find some *.rar, take it
309     return $1 if $subject =~ /(\w+\.rar)/;
310     # otherwise just pass what we have
311     return ();
312     }
313    
314     =back
315 root 1.1
316 root 1.11 =head1 LARGE EXAMPLE DECODER
317    
318     This is the file C<example-decoder> from the distribution, put here
319     instead of more thorough documentation.
320    
321     # decode all the files in the directory uusrc/ and copy
322     # the resulting files to uudst/
323    
324     use Convert::UUlib ':all';
325    
326     sub namefilter {
327     my($path)=@_;
328     $path=~s/^.*[\/\\]//;
329     $path;
330     }
331    
332     sub busycb {
333     my ($action, $curfile, $partno, $numparts, $percent, $fsize) = @_;
334     $_[0]=straction($action);
335     print "busy_callback(", (join ",",@_), ")\n";
336     0;
337     }
338    
339     SetOption OPT_IGNMODE, 1;
340     SetOption OPT_VERBOSE, 1;
341    
342     # show the three ways you can set callback functions. I normally
343     # prefer the one with the sub inplace.
344     SetFNameFilter \&namefilter;
345    
346     SetBusyCallback "busycb", 333;
347    
348     SetMsgCallback sub {
349     my ($msg, $level) = @_;
350     print uc strmsglevel $_[1], ": $msg\n";
351     };
352    
353     # the following non-trivial FileNameCallback takes care
354     # of some subject lines not detected properly by uulib:
355     SetFileNameCallback sub {
356     return unless $_[1]; # skip "Re:"-plies et al.
357     local $_ = $_[0];
358    
359     # the following rules are rather effective on some newsgroups,
360     # like alt.binaries.games.anime, where non-mime, uuencoded data
361     # is very common
362    
363     # if we find some *.rar, take it as the filename
364     return $1 if /(\S{3,}\.(?:[rstuvwxyz]\d\d|rar))\s/i;
365    
366     # one common subject format
367     return $1 if /- "(.{2,}?\..+?)" (?:yenc )?\(\d+\/\d+\)/i;
368    
369     # - filename.par (04/55)
370     return $1 if /- "?(\S{3,}\.\S+?)"? (?:yenc )?\(\d+\/\d+\)/i;
371    
372     # - (xxx) No. 1 sayuri81.jpg 756565 bytes
373     # - (20 files) No.17 Roseanne.jpg [2/2]
374     return $1 if /No\.[ 0-9]+ (\S+\....) (?:\d+ bytes )?\[/;
375    
376     # otherwise just pass what we have
377     return ();
378     };
379    
380     # now read all files in the directory uusrc/*
381     for(<uusrc/*>) {
382     my($retval,$count)=LoadFile ($_, $_, 1);
383     print "file($_), status(", strerror $retval, ") parts($count)\n";
384     }
385    
386     SetOption OPT_SAVEPATH, "uudst/";
387    
388     # now wade through all files and their source parts
389     $i = 0;
390     while ($uu = GetFileListItem($i)) {
391     $i++;
392     print "file nr. $i";
393     print " state ", $uu->state;
394     print " mode ", $uu->mode;
395     print " uudet ", strencoding $uu->uudet;
396     print " size ", $uu->size;
397     print " filename ", $uu->filename;
398     print " subfname ", $uu->subfname;
399     print " mimeid ", $uu->mimeid;
400     print " mimetype ", $uu->mimetype;
401     print "\n";
402    
403     # print additional info about all parts
404     for ($uu->parts) {
405     while (my ($k, $v) = each %$_) {
406     print "$k > $v, ";
407     }
408     print "\n";
409     }
410    
411     $uu->decode_temp;
412     print " temporarily decoded to ", $uu->binfile, "\n";
413     $uu->remove_temp;
414    
415     print strerror $uu->decode;
416     print " saved as uudst/", $uu->filename, "\n";
417     }
418    
419     print "cleanup...\n";
420    
421     CleanUp();
422    
423 root 1.1 =head1 AUTHOR
424    
425 root 1.11 Marc Lehmann <pcg@goof.com>, the original uulib library was written
426     by Frank Pilhofer <fp@informatik.uni-frankfurt.de>, and later heavily
427     bugfixed by Marc Lehmann.
428 root 1.1
429     =head1 SEE ALSO
430    
431     perl(1), uudeview homepage at http://www.uni-frankfurt.de/~fp/uudeview/.
432    
433     =cut