ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-UUlib/UUlib.pm
(Generate patch)

Comparing Convert-UUlib/UUlib.pm (file contents):
Revision 1.9 by root, Sat Apr 6 02:28:35 2002 UTC vs.
Revision 1.13 by root, Tue Oct 15 23:20:29 2002 UTC

2 2
3use Carp; 3use Carp;
4 4
5require Exporter; 5require Exporter;
6require DynaLoader; 6require DynaLoader;
7use AutoLoader;
8 7
9$VERSION = 0.212; 8$VERSION = 0.31;
10 9
11@ISA = qw(Exporter DynaLoader); 10@ISA = qw(Exporter DynaLoader);
12 11
13@_consts = qw( 12@_consts = qw(
14 ACT_COPYING ACT_DECODING ACT_ENCODING ACT_IDLE ACT_SCANNING 13 ACT_COPYING ACT_DECODING ACT_ENCODING ACT_IDLE ACT_SCANNING
24 OPT_VERSION OPT_REMOVE OPT_MOREMIME OPT_DOTDOT 23 OPT_VERSION OPT_REMOVE OPT_MOREMIME OPT_DOTDOT
25 24
26 RET_CANCEL RET_CONT RET_EXISTS RET_ILLVAL RET_IOERR RET_NODATA 25 RET_CANCEL RET_CONT RET_EXISTS RET_ILLVAL RET_IOERR RET_NODATA
27 RET_NOEND RET_NOMEM RET_OK RET_UNSUP 26 RET_NOEND RET_NOMEM RET_OK RET_UNSUP
28 27
29 B64ENCODED BH_ENCODED PT_ENCODED QP_ENCODED 28 B64_ENCODED BH_ENCODED PT_ENCODED QP_ENCODED
30 XX_ENCODED UU_ENCODED YENC_ENCODED 29 XX_ENCODED UU_ENCODED YENC_ENCODED
31); 30);
32 31
33@_funcs = qw( 32@_funcs = qw(
34 Initialize CleanUp GetOption SetOption strerror SetMsgCallback 33 Initialize CleanUp GetOption SetOption strerror SetMsgCallback
68} 67}
69 68
70# encoding type -> string mapping 69# encoding type -> string mapping
71sub strencoding($) { 70sub strencoding($) {
72 return 'uuencode' if $_[0] == &UU_ENCODED; 71 return 'uuencode' if $_[0] == &UU_ENCODED;
73 return 'base64' if $_[0] == &B64ENCODED; 72 return 'base64' if $_[0] == &B64_ENCODED;
74 return 'yenc' if $_[0] == &YENC_ENCODED; 73 return 'yenc' if $_[0] == &YENC_ENCODED;
75 return 'binhex' if $_[0] == &BH_ENCODED; 74 return 'binhex' if $_[0] == &BH_ENCODED;
76 return 'plaintext' if $_[0] == &PT_ENCODED; 75 return 'plaintext' if $_[0] == &PT_ENCODED;
77 return 'quoted-printable' if $_[0] == &QP_ENCODED; 76 return 'quoted-printable' if $_[0] == &QP_ENCODED;
78 return 'xxencode' if $_[0] == &XX_ENCODED; 77 return 'xxencode' if $_[0] == &XX_ENCODED;
96 95
97Convert::UUlib - Perl interface to the uulib library (a.k.a. uudeview/uuenview). 96Convert::UUlib - Perl interface to the uulib library (a.k.a. uudeview/uuenview).
98 97
99=head1 SYNOPSIS 98=head1 SYNOPSIS
100 99
101 use Convert::UUlib;
102
103=head1 DESCRIPTION
104
105Read the file uulibdoc.dvi.gz and the example-decoder source. Sorry - more
106to come once people use me ;)
107
108=head1 SMALL EXAMPLE DECODER
109
110The following code excerpt is a minimal decoder program. It reads all
111files given on the commandline and decodes any files in it.
112
113 use Convert::UUlib ':all'; 100 use Convert::UUlib ':all';
114 101
102 # read all the files named on the commandline and decode them
103 # into the CURRENT directory. See below for a longer example.
115 LoadFile($_) for @ARGV; 104 LoadFile $_ for @ARGV;
116
117 for($i=0; $uu=GetFileListItem($i); $i++) { 105 for (my $i = 0; my $uu = GetFileListItem $i; $i++) {
118 $uu->decode if $uu->state & FILE_OK; 106 if ($uu->state & FILE_OK) {
107 $uu->decode;
108 print $uu->filename, "\n";
109 }
119 } 110 }
120 111
121=head1 LARGE EXAMPLE DECODER 112=head1 DESCRIPTION
122 113
123This is the file C<example-decoder> from the distribution, put here 114Read the file doc/library.pdf from the distribution for in-depth
124instead of more thorough documentation. 115information about the C-library used in this interface, and the rest of
116this document and especially the non-trivial decoder program at the end.
125 117
126 # decode all the files in the directory uusrc/ and copy 118=head1 EXPORTED CONSTANTS
127 # the resulting files to uudst/
128 119
129 use Convert::UUlib ':all'; 120=head2 Action code constants
130 121
131 sub namefilter { 122 ACT_IDLE we don't do anything
132 my($path)=@_; 123 ACT_SCANNING scanning an input file
133 $path=~s/^.*[\/\\]//; 124 ACT_DECODING decoding into a temp file
134 $path; 125 ACT_COPYING copying temp to target
126 ACT_ENCODING encoding a file
127
128=head2 Message severity levels
129
130 MSG_MESSAGE just a message, nothing important
131 MSG_NOTE something that should be noticed
132 MSG_WARNING important msg, processing continues
133 MSG_ERROR processing has been terminated
134 MSG_FATAL decoder cannot process further requests
135 MSG_PANIC recovery impossible, app must terminate
136
137=head2 Options
138
139 OPT_VERSION version number MAJOR.MINORplPATCH (ro)
140 OPT_FAST assumes only one part per file
141 OPT_DUMBNESS switch off the program's intelligence
142 OPT_BRACKPOL give numbers in [] higher precendence
143 OPT_VERBOSE generate informative messages
144 OPT_DESPERATE try to decode incomplete files
145 OPT_IGNREPLY ignore RE:plies (off by default)
146 OPT_OVERWRITE whether it's OK to overwrite ex. files
147 OPT_SAVEPATH prefix to save-files on disk
148 OPT_IGNMODE ignore the original file mode
149 OPT_DEBUG print messages with FILE/LINE info
150 OPT_ERRNO get last error code for RET_IOERR (ro)
151 OPT_PROGRESS retrieve progress information
152 OPT_USETEXT handle text messages
153 OPT_PREAMB handle Mime preambles/epilogues
154 OPT_TINYB64 detect short B64 outside of Mime
155 OPT_ENCEXT extension for single-part encoded files
156 OPT_REMOVE remove input files after decoding
157 OPT_MOREMIME strict MIME adherence
158 OPT_DOTDOT .. unescaping has not yet been done on input files
159
160=head2 Result/Error codes
161
162 RET_OK everything went fine
163 RET_IOERR I/O Error - examine errno
164 RET_NOMEM not enough memory
165 RET_ILLVAL illegal value for operation
166 RET_NODATA decoder didn't find any data
167 RET_NOEND encoded data wasn't ended properly
168 RET_UNSUP unsupported function (encoding)
169 RET_EXISTS file exists (decoding)
170 RET_CONT continue -- special from ScanPart
171 RET_CANCEL operation canceled
172
173=head2 File States
174
175 This code is zero, i.e. "false":
176
177 UUFILE_READ Read in, but not further processed
178
179 The following state codes are or'ed together:
180
181 FILE_MISPART Missing Part(s) detected
182 FILE_NOBEGIN No 'begin' found
183 FILE_NOEND No 'end' found
184 FILE_NODATA File does not contain valid uudata
185 FILE_OK All Parts found, ready to decode
186 FILE_ERROR Error while decoding
187 FILE_DECODED Successfully decoded
188 FILE_TMPFILE Temporary decoded file exists
189
190=head2 Encoding types
191
192 UU_ENCODED UUencoded data
193 B64_ENCODED Mime-Base64 data
194 XX_ENCODED XXencoded data
195 BH_ENCODED Binhex encoded
196 PT_ENCODED Plain-Text encoded (MIME)
197 QP_ENCODED Quoted-Printable (MIME)
198 YENC_ENCODED yEnc encoded (non-MIME)
199
200=head1 EXPORTED FUNCTIONS
201
202=head2 Initializing and cleanup
203
204Initialize is automatically called when the module is loaded and allocates
205quite a small amount of memory for todays machines ;) CleanUp releases that
206again.
207
208=over 4
209
210=item Initialize
211
212Not normally necessary, (re-)initializes the library.
213
214=item CleanUp
215
216Not normally necessary, could be called at the end to release memory
217before starting a new decoding round.
218
219=back
220
221=head2 Setting and querying options
222
223=over 4
224
225=item $option = GetOption OPT_xxx
226
227=item SetOption OPT_xxx, opt-value
228
229=back
230
231See the C<OPT_xxx> constants above to see which options exist.
232
233=head2 Setting various callbacks
234
235=over 4
236
237=item SetMsgCallback [callback-function]
238
239=item SetBusyCallback [callback-function]
240
241=item SetFileCallback [callback-function]
242
243=item SetFNameFilter [callback-function]
244
245=back
246
247=head2 Call the currently selected FNameFilter
248
249=over 4
250
251=item $file = FNameFilter $file
252
253=back
254
255=head2 Loading sourcefiles, optionally fuzzy merge and start decoding
256
257=over 4
258
259=item ($retval, $count) = LoadFile $fname, [$id, [$delflag]]
260
261Load the given file and scan it for encoded contents. Optionally tag it
262with the given id, and if C<$delflag> is true, delete the file after it is
263no longer necessary.
264
265=item $retval = Smerge $pass
266
267If you are desperate, try to call C<Smerge> with increasing C<$pass>
268values, beginning at C<0>, to try to merge parts that usually would not
269have been merged.
270
271Most probably this will result in garbled files, so never do this by
272default.
273
274=item $item = GetFileListItem $item_number
275
276Return the C<$item> structure for the C<$item_number>'th found file, or
277C<undef> of no file with that number exists.
278
279The first file has number C<0>, and the series has no holes, so you can
280iterate over all files by starting with zero and incrementing until you
281hit C<undef>.
282
283=back
284
285=head2 Decoding files
286
287=over 4
288
289=item $retval = $item->rename($newname)
290
291Change the ondisk filename where the decoded file will be saved.
292
293=item $retval = $item->decode_temp
294
295Decode the file into a temporary location, use C<< $item->infile >> to
296retrieve the temporary filename.
297
298=item $retval = $item->remove_temp
299
300Remove the temporarily decoded file again.
301
302=item $retval = $item->decode([$target_path])
303
304Decode the file to it's destination, or the given target path.
305
306=item $retval = $item->info(callback-function)
307
308=back
309
310=head2 Querying (and setting) item attributes
311
312=over 4
313
314=item $state = $item->state
315
316=item $mode = $item->mode([newmode])
317
318=item $uudet = $item->uudet
319
320=item $size = $item->size
321
322=item $filename = $item->filename([newfilename})
323
324=item $subfname = $item->subfname
325
326=item $mimeid = $item->mimeid
327
328=item $mimetype = $item->mimetype
329
330=item $binfile = $item->binfile
331
332=back
333
334=head2 Information about source parts
335
336=over 4
337
338=item $parts = $item->parts
339
340Return information about all parts (source files) used to decode the file
341as a list of hashrefs with the following structure:
342
343 {
344 partno => <integer describing the part number, starting with 1>,
345 # the following member sonly exist when they contain useful information
346 sfname => <local pathname of the file where this part is from>,
347 filename => <the ondisk filename of the decoded file>,
348 subfname => <used to cluster postings, possibly the posting filename>,
349 subject => <the subject of the posting/mail>,
350 origin => <the possible source (From) address>,
351 mimetype => <the possible mimetype of the decoded file>,
352 mimeid => <the id part of the Content-Type>,
135 } 353 }
136 354
137 sub busycb { 355Usually you are interested mostly the C<sfname> and possibly the C<partno>
138 my($action,$curfile,$partno,$numparts,$percent,$fsize)=@_; 356and C<filename> members.
139 $_[0]=straction($action);
140 print "busy_callback(",join(",",@_),")\n";
141 0;
142 }
143 357
144 SetOption (OPT_IGNMODE, 1); 358=back
145 SetOption (OPT_VERBOSE, 1);
146 359
147 # show the three ways you can set callback functions
148 SetFNameFilter (\&namefilter);
149
150 SetBusyCallback ("busycb",333);
151
152 SetMsgCallback (sub {
153 my($msg,$level)=@_;
154 print uc(strmsglevel($_[1])),": $msg\n";
155 });
156
157 for(<uusrc/*>) {
158 my($retval,$count)=LoadFile ($_,$_,1);
159 print "file($_), status(",strerror($retval),") parts($count)\n";
160 }
161
162 SetOption (OPT_SAVEPATH, "uudst/");
163
164 $i=0;
165 while($uu=GetFileListItem($i)) {
166 $i++;
167 print "file nr. $i";
168 print " state ",$uu->state;
169 print " mode ",$uu->mode;
170 print " uudet ",strencoding($uu->uudet);
171 print " size ",$uu->size;
172 print " filename ",$uu->filename;
173 print " subfname ",$uu->subfname;
174 print " mimeid ",$uu->mimeid;
175 print " mimetype ",$uu->mimetype;
176 print "\n";
177
178 # print additional info about all parts
179 for($uu->parts) {
180 while(my($k,$v)=each(%$_)) {
181 print "$k > $v, ";
182 }
183 print "\n";
184 }
185
186 $uu->decode_temp;
187 print " temporarily decoded to ",$uu->binfile,"\n";
188 $uu->remove_temp;
189
190 print strerror($uu->decode);
191 print " saved as uudst/",$uu->filename,"\n";
192 }
193
194 print "cleanup...\n";
195
196 CleanUp();
197
198=head1 Exported constants
199
200Action code constants:
201
202 ACT_COPYING ACT_DECODING ACT_ENCODING
203 ACT_IDLE ACT_SCANNING
204
205File status flags:
206
207 FILE_DECODED FILE_ERROR FILE_MISPART
208 FILE_NOBEGIN FILE_NODATA FILE_NOEND
209 FILE_OK FILE_READ FILE_TMPFILE
210
211Message severity levels:
212
213 MSG_ERROR MSG_FATAL MSG_MESSAGE
214 MSG_NOTE MSG_PANIC MSG_WARNING
215
216Options:
217
218 OPT_BRACKPOL OPT_DEBUG OPT_DESPERATE OPT_DUMBNESS
219 OPT_ENCEXT OPT_ERRNO OPT_FAST OPT_IGNMODE
220 OPT_IGNREPLY OPT_OVERWRITE OPT_PREAMB OPT_PROGRESS
221 OPT_SAVEPATH OPT_TINYB64 OPT_USETEXT OPT_VERBOSE
222 OPT_VERSION OPT_REMOVE OPT_MOREMIME
223
224Error/Result codes:
225
226 RET_CANCEL RET_CONT RET_EXISTS RET_ILLVAL RET_IOERR
227 RET_NODATA RET_NOEND RET_NOMEM RET_OK RET_UNSUP
228
229Encoding types:
230
231 B64ENCODED BH_ENCODED PT_ENCODED QP_ENCODED XX_ENCODED
232 UU_ENCODED YENC_ENCODED
233
234=head1 Exported functions
235
236Initializing and cleanup (Initialize is automatically called when the
237module is loaded and allocates quite a bit of memory. CleanUp releases
238that again).
239
240 Initialize; # not normally necessary
241 CleanUp; # could be called at the end to release memory
242
243Setting and querying options:
244
245 $option = GetOption OPT_xxx;
246 SetOption OPT_xxx, opt-value;
247
248Error and action values => stringified:
249
250 $msg = straction ACT_xxx;
251 $msg = strerror RET_xxx;
252
253Setting various callbacks:
254
255 SetMsgCallback [callback-function];
256 SetBusyCallback [callback-function];
257 SetFileCallback [callback-function];
258 SetFNameFilter [callback-function];
259
260Call the currently selected FNameFilter:
261
262 $file = FNameFilter $file;
263
264Loading sourcefiles, optionally fuzzy merge and start decoding:
265
266 ($retval, $count) = LoadFile $fname, [$id, [$delflag]];
267 $retval = Smerge $pass;
268 $item = GetFileListItem $item_number;
269
270The procedural interface is undocumented, use the following methods instead:
271
272 $retval = $item->rename($newname);
273 $retval = $item->decode_temp;
274 $retval = $item->remove_temp;
275 $retval = $item->decode([$target_path]);
276 $retval = $item->info(callback-function);
277
278Querying (and setting) item attributes:
279
280 $state = $item->state;
281 $mode = $item->mode([newmode]);
282 $uudet = $item->uudet;
283 $size = $item->size;
284 $filename = $item->filename([newfilename});
285 $subfname = $item->subfname;
286 $mimeid = $item->mimeid;
287 $mimetype = $item->mimetype;
288 $binfile = $item->binfile;
289
290Totally undocumented and unsupported(!):
291
292 $parts = $item->parts;
293
294Functions below not documented and not very well tested: 360=head2 Functions below not documented and not very well tested
295 361
296 int QuickDecode () ; 362 QuickDecode
297 int EncodeMulti () ; 363 EncodeMulti
298 int EncodePartial () ; 364 EncodePartial
299 int EncodeToStream () ; 365 EncodeToStream
300 int EncodeToFile () ; 366 EncodeToFile
301 int E_PrepSingle () ; 367 E_PrepSingle
302 int E_PrepPartial () ; 368 E_PrepPartial
303 369
304=head2 EXTENSION FUNCTIONS 370=head2 EXTENSION FUNCTIONS
305 371
306Functions found in this module but not documented in the uulib documentation: 372Functions found in this module but not documented in the uulib documentation:
307 373
308=over 4 374=over 4
375
376=item $msg = straction ACT_xxx
377
378Return a human readable string representing the given action code.
379
380=item $msg = strerror RET_xxx
381
382Return a human readable string representing the given error code.
383
384=item $str = strencoding xxx_ENCODED
385
386Return the name of the encoding type as a string.
387
388=item $str = strmsglevel MSG_xxx
389
390Returns the message level as a string.
309 391
310=item SetFileNameCallback $cb 392=item SetFileNameCallback $cb
311 393
312Sets (or queries) the FileNameCallback, which is called whenever the 394Sets (or queries) the FileNameCallback, which is called whenever the
313decoding library can't find a filename and wants to extract a filename 395decoding library can't find a filename and wants to extract a filename
336 return (); 418 return ();
337 } 419 }
338 420
339=back 421=back
340 422
423=head1 LARGE EXAMPLE DECODER
424
425This is the file C<example-decoder> from the distribution, put here
426instead of more thorough documentation.
427
428 # decode all the files in the directory uusrc/ and copy
429 # the resulting files to uudst/
430
431 use Convert::UUlib ':all';
432
433 sub namefilter {
434 my($path)=@_;
435 $path=~s/^.*[\/\\]//;
436 $path;
437 }
438
439 sub busycb {
440 my ($action, $curfile, $partno, $numparts, $percent, $fsize) = @_;
441 $_[0]=straction($action);
442 print "busy_callback(", (join ",",@_), ")\n";
443 0;
444 }
445
446 SetOption OPT_IGNMODE, 1;
447 SetOption OPT_VERBOSE, 1;
448
449 # show the three ways you can set callback functions. I normally
450 # prefer the one with the sub inplace.
451 SetFNameFilter \&namefilter;
452
453 SetBusyCallback "busycb", 333;
454
455 SetMsgCallback sub {
456 my ($msg, $level) = @_;
457 print uc strmsglevel $_[1], ": $msg\n";
458 };
459
460 # the following non-trivial FileNameCallback takes care
461 # of some subject lines not detected properly by uulib:
462 SetFileNameCallback sub {
463 return unless $_[1]; # skip "Re:"-plies et al.
464 local $_ = $_[0];
465
466 # the following rules are rather effective on some newsgroups,
467 # like alt.binaries.games.anime, where non-mime, uuencoded data
468 # is very common
469
470 # if we find some *.rar, take it as the filename
471 return $1 if /(\S{3,}\.(?:[rstuvwxyz]\d\d|rar))\s/i;
472
473 # one common subject format
474 return $1 if /- "(.{2,}?\..+?)" (?:yenc )?\(\d+\/\d+\)/i;
475
476 # - filename.par (04/55)
477 return $1 if /- "?(\S{3,}\.\S+?)"? (?:yenc )?\(\d+\/\d+\)/i;
478
479 # - (xxx) No. 1 sayuri81.jpg 756565 bytes
480 # - (20 files) No.17 Roseanne.jpg [2/2]
481 return $1 if /No\.[ 0-9]+ (\S+\....) (?:\d+ bytes )?\[/;
482
483 # otherwise just pass what we have
484 return ();
485 };
486
487 # now read all files in the directory uusrc/*
488 for(<uusrc/*>) {
489 my($retval,$count)=LoadFile ($_, $_, 1);
490 print "file($_), status(", strerror $retval, ") parts($count)\n";
491 }
492
493 SetOption OPT_SAVEPATH, "uudst/";
494
495 # now wade through all files and their source parts
496 $i = 0;
497 while ($uu = GetFileListItem($i)) {
498 $i++;
499 print "file nr. $i";
500 print " state ", $uu->state;
501 print " mode ", $uu->mode;
502 print " uudet ", strencoding $uu->uudet;
503 print " size ", $uu->size;
504 print " filename ", $uu->filename;
505 print " subfname ", $uu->subfname;
506 print " mimeid ", $uu->mimeid;
507 print " mimetype ", $uu->mimetype;
508 print "\n";
509
510 # print additional info about all parts
511 for ($uu->parts) {
512 while (my ($k, $v) = each %$_) {
513 print "$k > $v, ";
514 }
515 print "\n";
516 }
517
518 $uu->decode_temp;
519 print " temporarily decoded to ", $uu->binfile, "\n";
520 $uu->remove_temp;
521
522 print strerror $uu->decode;
523 print " saved as uudst/", $uu->filename, "\n";
524 }
525
526 print "cleanup...\n";
527
528 CleanUp();
529
341=head1 AUTHOR 530=head1 AUTHOR
342 531
343Marc Lehmann <pcg@goof.com>, the original uulib library was written by 532Marc Lehmann <pcg@goof.com>, the original uulib library was written
344Frank Pilhofer <fp@informatik.uni-frankfurt.de>. 533by Frank Pilhofer <fp@informatik.uni-frankfurt.de>, and later heavily
534bugfixed by Marc Lehmann.
345 535
346=head1 SEE ALSO 536=head1 SEE ALSO
347 537
348perl(1), uudeview homepage at http://www.uni-frankfurt.de/~fp/uudeview/. 538perl(1), uudeview homepage at http://www.uni-frankfurt.de/~fp/uudeview/.
349 539

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines