--- Convert-UUlib/UUlib.pm 2002/08/19 23:25:34 1.10 +++ Convert-UUlib/UUlib.pm 2002/10/13 13:47:09 1.11 @@ -6,7 +6,7 @@ require DynaLoader; use AutoLoader; -$VERSION = 0.213; +$VERSION = 0.214; @ISA = qw(Exporter DynaLoader); @@ -26,7 +26,7 @@ RET_CANCEL RET_CONT RET_EXISTS RET_ILLVAL RET_IOERR RET_NODATA RET_NOEND RET_NOMEM RET_OK RET_UNSUP - B64ENCODED BH_ENCODED PT_ENCODED QP_ENCODED + B64_ENCODED BH_ENCODED PT_ENCODED QP_ENCODED XX_ENCODED UU_ENCODED YENC_ENCODED ); @@ -70,7 +70,7 @@ # encoding type -> string mapping sub strencoding($) { return 'uuencode' if $_[0] == &UU_ENCODED; - return 'base64' if $_[0] == &B64ENCODED; + return 'base64' if $_[0] == &B64_ENCODED; return 'yenc' if $_[0] == &YENC_ENCODED; return 'binhex' if $_[0] == &BH_ENCODED; return 'plaintext' if $_[0] == &PT_ENCODED; @@ -98,176 +98,135 @@ =head1 SYNOPSIS - use Convert::UUlib; - -=head1 DESCRIPTION - -Read the file uulibdoc.dvi.gz and the example-decoder source. Sorry - more -to come once people use me ;) - -=head1 SMALL EXAMPLE DECODER - -The following code excerpt is a minimal decoder program. It reads all -files given on the commandline and decodes any files in it. - use Convert::UUlib ':all'; + # read all the files named on the commandline and decode them LoadFile($_) for @ARGV; - for($i=0; $uu=GetFileListItem($i); $i++) { $uu->decode if $uu->state & FILE_OK; } -=head1 LARGE EXAMPLE DECODER - -This is the file C from the distribution, put here -instead of more thorough documentation. - - # decode all the files in the directory uusrc/ and copy - # the resulting files to uudst/ - - use Convert::UUlib ':all'; - - sub namefilter { - my($path)=@_; - $path=~s/^.*[\/\\]//; - $path; - } - - sub busycb { - my($action,$curfile,$partno,$numparts,$percent,$fsize)=@_; - $_[0]=straction($action); - print "busy_callback(",join(",",@_),")\n"; - 0; - } - - SetOption (OPT_IGNMODE, 1); - SetOption (OPT_VERBOSE, 1); - - # show the three ways you can set callback functions - SetFNameFilter (\&namefilter); - - SetBusyCallback ("busycb",333); - - SetMsgCallback (sub { - my($msg,$level)=@_; - print uc(strmsglevel($_[1])),": $msg\n"; - }); - - for() { - my($retval,$count)=LoadFile ($_,$_,1); - print "file($_), status(",strerror($retval),") parts($count)\n"; - } - - SetOption (OPT_SAVEPATH, "uudst/"); - - $i=0; - while($uu=GetFileListItem($i)) { - $i++; - print "file nr. $i"; - print " state ",$uu->state; - print " mode ",$uu->mode; - print " uudet ",strencoding($uu->uudet); - print " size ",$uu->size; - print " filename ",$uu->filename; - print " subfname ",$uu->subfname; - print " mimeid ",$uu->mimeid; - print " mimetype ",$uu->mimetype; - print "\n"; - - # print additional info about all parts - for($uu->parts) { - while(my($k,$v)=each(%$_)) { - print "$k > $v, "; - } - print "\n"; - } - - $uu->decode_temp; - print " temporarily decoded to ",$uu->binfile,"\n"; - $uu->remove_temp; - - print strerror($uu->decode); - print " saved as uudst/",$uu->filename,"\n"; - } - - print "cleanup...\n"; - - CleanUp(); - -=head1 Exported constants - -Action code constants: - - ACT_COPYING ACT_DECODING ACT_ENCODING - ACT_IDLE ACT_SCANNING - -File status flags: - - FILE_DECODED FILE_ERROR FILE_MISPART - FILE_NOBEGIN FILE_NODATA FILE_NOEND - FILE_OK FILE_READ FILE_TMPFILE - -Message severity levels: - - MSG_ERROR MSG_FATAL MSG_MESSAGE - MSG_NOTE MSG_PANIC MSG_WARNING - -Options: - - OPT_BRACKPOL OPT_DEBUG OPT_DESPERATE OPT_DUMBNESS - OPT_ENCEXT OPT_ERRNO OPT_FAST OPT_IGNMODE - OPT_IGNREPLY OPT_OVERWRITE OPT_PREAMB OPT_PROGRESS - OPT_SAVEPATH OPT_TINYB64 OPT_USETEXT OPT_VERBOSE - OPT_VERSION OPT_REMOVE OPT_MOREMIME - -Error/Result codes: - - RET_CANCEL RET_CONT RET_EXISTS RET_ILLVAL RET_IOERR - RET_NODATA RET_NOEND RET_NOMEM RET_OK RET_UNSUP +=head1 DESCRIPTION -Encoding types: +Read the file doc/library.pdf from the distribution for in-depth +information about the C-library used in this interface, and the rest of +this document and especially the non-trivial decoder program at the end. + +=head1 EXPORTED CONSTANTS + +=head2 Action code constants + + ACT_IDLE we don't do anything + ACT_SCANNING scanning an input file + ACT_DECODING decoding into a temp file + ACT_COPYING copying temp to target + ACT_ENCODING encoding a file + +=head2 Message severity levels + + MSG_MESSAGE just a message, nothing important + MSG_NOTE something that should be noticed + MSG_WARNING important msg, processing continues + MSG_ERROR processing has been terminated + MSG_FATAL decoder cannot process further requests + MSG_PANIC recovery impossible, app must terminate + +=head2 Options + + OPT_VERSION version number MAJOR.MINORplPATCH (ro) + OPT_FAST assumes only one part per file + OPT_DUMBNESS switch off the program's intelligence + OPT_BRACKPOL give numbers in [] higher precendence + OPT_VERBOSE generate informative messages + OPT_DESPERATE try to decode incomplete files + OPT_IGNREPLY ignore RE:plies (off by default) + OPT_OVERWRITE whether it's OK to overwrite ex. files + OPT_SAVEPATH prefix to save-files on disk + OPT_IGNMODE ignore the original file mode + OPT_DEBUG print messages with FILE/LINE info + OPT_ERRNO get last error code for RET_IOERR (ro) + OPT_PROGRESS retrieve progress information + OPT_USETEXT handle text messages + OPT_PREAMB handle Mime preambles/epilogues + OPT_TINYB64 detect short B64 outside of Mime + OPT_ENCEXT extension for single-part encoded files + OPT_REMOVE remove input files after decoding + OPT_MOREMIME strict MIME adherence + OPT_DOTDOT .. unescaping has not yet been done on input files + +=head2 Result/Error codes + + RET_OK everything went fine + RET_IOERR I/O Error - examine errno + RET_NOMEM not enough memory + RET_ILLVAL illegal value for operation + RET_NODATA decoder didn't find any data + RET_NOEND encoded data wasn't ended properly + RET_UNSUP unsupported function (encoding) + RET_EXISTS file exists (decoding) + RET_CONT continue -- special from ScanPart + RET_CANCEL operation canceled + +=head2 File States + + This code is zero, i.e. "false": + + UUFILE_READ Read in, but not further processed + + The following state codes are ored together: + + FILE_MISPART Missing Part(s) detected + FILE_NOBEGIN No 'begin' found + FILE_NOEND No 'end' found + FILE_NODATA File does not contain valid uudata + FILE_OK All Parts found, ready to decode + FILE_ERROR Error while decoding + FILE_DECODED Successfully decoded + FILE_TMPFILE Temporary decoded file exists + +=head2 Encoding types + + UU_ENCODED UUencoded data + B64_ENCODED Mime-Base64 data + XX_ENCODED XXencoded data + BH_ENCODED Binhex encoded + PT_ENCODED Plain-Text encoded (MIME) + QP_ENCODED Quoted-Printable (MIME) + YENC_ENCODED yEnc encoded (non-MIME) - B64ENCODED BH_ENCODED PT_ENCODED QP_ENCODED XX_ENCODED - UU_ENCODED YENC_ENCODED +=head1 EXPORTED FUNCTIONS -=head1 Exported functions +=head2 Initializing and cleanup -Initializing and cleanup (Initialize is automatically called when the -module is loaded and allocates quite a bit of memory. CleanUp releases -that again). +Initialize is automatically called when the module is loaded and allocates +quite a bit of memory. CleanUp releases that again. Initialize; # not normally necessary CleanUp; # could be called at the end to release memory -Setting and querying options: +=head2 Setting and querying options $option = GetOption OPT_xxx; SetOption OPT_xxx, opt-value; -Error and action values => stringified: - - $msg = straction ACT_xxx; - $msg = strerror RET_xxx; - -Setting various callbacks: +=head2 Setting various callbacks SetMsgCallback [callback-function]; SetBusyCallback [callback-function]; SetFileCallback [callback-function]; SetFNameFilter [callback-function]; -Call the currently selected FNameFilter: +=head2 Call the currently selected FNameFilter $file = FNameFilter $file; -Loading sourcefiles, optionally fuzzy merge and start decoding: +=head2 Loading sourcefiles, optionally fuzzy merge and start decoding ($retval, $count) = LoadFile $fname, [$id, [$delflag]]; $retval = Smerge $pass; $item = GetFileListItem $item_number; -The procedural interface is undocumented, use the following methods instead: +=head2 The procedural interface is undocumented, use the following methods instead $retval = $item->rename($newname); $retval = $item->decode_temp; @@ -275,7 +234,7 @@ $retval = $item->decode([$target_path]); $retval = $item->info(callback-function); -Querying (and setting) item attributes: +=head2 Querying (and setting) item attributes $state = $item->state; $mode = $item->mode([newmode]); @@ -287,19 +246,19 @@ $mimetype = $item->mimetype; $binfile = $item->binfile; -Totally undocumented and unsupported(!): +=head2 Totally undocumented but well tested ;) $parts = $item->parts; -Functions below not documented and not very well tested: +=head2 Functions below not documented and not very well tested - int QuickDecode () ; - int EncodeMulti () ; - int EncodePartial () ; - int EncodeToStream () ; - int EncodeToFile () ; - int E_PrepSingle () ; - int E_PrepPartial () ; + QuickDecode + EncodeMulti + EncodePartial + EncodeToStream + EncodeToFile + E_PrepSingle + E_PrepPartial =head2 EXTENSION FUNCTIONS @@ -307,6 +266,22 @@ =over 4 +=item $msg = straction ACT_xxx + +Return a human readable string representing the given action code. + +=item $msg = strerror RET_xxx + +Return a human readable string representing the given error code. + +=item $str = strencoding xxx_ENCODED + +Return the name of the encoding type as a string. + +=item $str = strmsglevel MSG_xxx + +Returns the message level as a string. + =item SetFileNameCallback $cb Sets (or queries) the FileNameCallback, which is called whenever the @@ -338,10 +313,118 @@ =back +=head1 LARGE EXAMPLE DECODER + +This is the file C from the distribution, put here +instead of more thorough documentation. + + # decode all the files in the directory uusrc/ and copy + # the resulting files to uudst/ + + use Convert::UUlib ':all'; + + sub namefilter { + my($path)=@_; + $path=~s/^.*[\/\\]//; + $path; + } + + sub busycb { + my ($action, $curfile, $partno, $numparts, $percent, $fsize) = @_; + $_[0]=straction($action); + print "busy_callback(", (join ",",@_), ")\n"; + 0; + } + + SetOption OPT_IGNMODE, 1; + SetOption OPT_VERBOSE, 1; + + # show the three ways you can set callback functions. I normally + # prefer the one with the sub inplace. + SetFNameFilter \&namefilter; + + SetBusyCallback "busycb", 333; + + SetMsgCallback sub { + my ($msg, $level) = @_; + print uc strmsglevel $_[1], ": $msg\n"; + }; + + # the following non-trivial FileNameCallback takes care + # of some subject lines not detected properly by uulib: + SetFileNameCallback sub { + return unless $_[1]; # skip "Re:"-plies et al. + local $_ = $_[0]; + + # the following rules are rather effective on some newsgroups, + # like alt.binaries.games.anime, where non-mime, uuencoded data + # is very common + + # if we find some *.rar, take it as the filename + return $1 if /(\S{3,}\.(?:[rstuvwxyz]\d\d|rar))\s/i; + + # one common subject format + return $1 if /- "(.{2,}?\..+?)" (?:yenc )?\(\d+\/\d+\)/i; + + # - filename.par (04/55) + return $1 if /- "?(\S{3,}\.\S+?)"? (?:yenc )?\(\d+\/\d+\)/i; + + # - (xxx) No. 1 sayuri81.jpg 756565 bytes + # - (20 files) No.17 Roseanne.jpg [2/2] + return $1 if /No\.[ 0-9]+ (\S+\....) (?:\d+ bytes )?\[/; + + # otherwise just pass what we have + return (); + }; + + # now read all files in the directory uusrc/* + for() { + my($retval,$count)=LoadFile ($_, $_, 1); + print "file($_), status(", strerror $retval, ") parts($count)\n"; + } + + SetOption OPT_SAVEPATH, "uudst/"; + + # now wade through all files and their source parts + $i = 0; + while ($uu = GetFileListItem($i)) { + $i++; + print "file nr. $i"; + print " state ", $uu->state; + print " mode ", $uu->mode; + print " uudet ", strencoding $uu->uudet; + print " size ", $uu->size; + print " filename ", $uu->filename; + print " subfname ", $uu->subfname; + print " mimeid ", $uu->mimeid; + print " mimetype ", $uu->mimetype; + print "\n"; + + # print additional info about all parts + for ($uu->parts) { + while (my ($k, $v) = each %$_) { + print "$k > $v, "; + } + print "\n"; + } + + $uu->decode_temp; + print " temporarily decoded to ", $uu->binfile, "\n"; + $uu->remove_temp; + + print strerror $uu->decode; + print " saved as uudst/", $uu->filename, "\n"; + } + + print "cleanup...\n"; + + CleanUp(); + =head1 AUTHOR -Marc Lehmann , the original uulib library was written by -Frank Pilhofer . +Marc Lehmann , the original uulib library was written +by Frank Pilhofer , and later heavily +bugfixed by Marc Lehmann. =head1 SEE ALSO