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

File Contents

# Content
1 package Convert::UUlib;
2
3 use Carp;
4
5 require Exporter;
6 require DynaLoader;
7 use AutoLoader;
8
9 $VERSION = 0.3;
10
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 OPT_VERSION OPT_REMOVE OPT_MOREMIME OPT_DOTDOT
25
26 RET_CANCEL RET_CONT RET_EXISTS RET_ILLVAL RET_IOERR RET_NODATA
27 RET_NOEND RET_NOMEM RET_OK RET_UNSUP
28
29 B64_ENCODED BH_ENCODED PT_ENCODED QP_ENCODED
30 XX_ENCODED UU_ENCODED YENC_ENCODED
31 );
32
33 @_funcs = qw(
34 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
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 'unknown';
68 }
69
70 # encoding type -> string mapping
71 sub strencoding($) {
72 return 'uuencode' if $_[0] == &UU_ENCODED;
73 return 'base64' if $_[0] == &B64_ENCODED;
74 return 'yenc' if $_[0] == &YENC_ENCODED;
75 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 'unknown';
80 }
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 'unknown';
90 }
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 # read all the files named on the commandline and decode them
104 LoadFile($_) for @ARGV;
105 for($i=0; $uu=GetFileListItem($i); $i++) {
106 $uu->decode if $uu->state & FILE_OK;
107 }
108
109 =head1 DESCRIPTION
110
111 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
197 =head1 EXPORTED FUNCTIONS
198
199 =head2 Initializing and cleanup
200
201 Initialize is automatically called when the module is loaded and allocates
202 quite a bit of memory. CleanUp releases that again.
203
204 Initialize; # not normally necessary
205 CleanUp; # could be called at the end to release memory
206
207 =head2 Setting and querying options
208
209 $option = GetOption OPT_xxx;
210 SetOption OPT_xxx, opt-value;
211
212 =head2 Setting various callbacks
213
214 SetMsgCallback [callback-function];
215 SetBusyCallback [callback-function];
216 SetFileCallback [callback-function];
217 SetFNameFilter [callback-function];
218
219 =head2 Call the currently selected FNameFilter
220
221 $file = FNameFilter $file;
222
223 =head2 Loading sourcefiles, optionally fuzzy merge and start decoding
224
225 ($retval, $count) = LoadFile $fname, [$id, [$delflag]];
226 $retval = Smerge $pass;
227 $item = GetFileListItem $item_number;
228
229 =head2 The procedural interface is undocumented, use the following methods instead
230
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 =head2 Querying (and setting) item attributes
238
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 =head2 Totally undocumented but well tested ;)
250
251 $parts = $item->parts;
252
253 =head2 Functions below not documented and not very well tested
254
255 QuickDecode
256 EncodeMulti
257 EncodePartial
258 EncodeToStream
259 EncodeToFile
260 E_PrepSingle
261 E_PrepPartial
262
263 =head2 EXTENSION FUNCTIONS
264
265 Functions found in this module but not documented in the uulib documentation:
266
267 =over 4
268
269 =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 =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
316 =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 =head1 AUTHOR
424
425 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
429 =head1 SEE ALSO
430
431 perl(1), uudeview homepage at http://www.uni-frankfurt.de/~fp/uudeview/.
432
433 =cut