home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-04-02 | 54.2 KB | 1,803 lines |
- Newsgroups: comp.sources.misc
- From: info-zip@cs.ucla.edu (Info-Zip)
- Subject: v29i038: unzip - Info-ZIP's portable UnZip v4.2, Part08/12
- Message-ID: <1992Apr3.063305.29044@sparky.imd.sterling.com>
- X-Md4-Signature: 66b1fd790fcb8bcabe1524123e87542d
- Date: Fri, 3 Apr 1992 06:33:05 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: info-zip@cs.ucla.edu (Info-Zip)
- Posting-number: Volume 29, Issue 38
- Archive-name: unzip/part08
- Environment: Unix, VMS, OS/2, MS-DOS, Amiga, Macintosh
- Supersedes: unzip, Volume 19, Issues 96-101
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: MSDOS/bcc/unzip_cr.prj.u VMS/VMSmunch.c VMS/vms.c
- # unimplod.c
- # Wrapped by kent@sparky on Mon Mar 30 01:45:54 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 8 (of 12)."'
- if test -f 'MSDOS/bcc/unzip_cr.prj.u' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MSDOS/bcc/unzip_cr.prj.u'\"
- else
- echo shar: Extracting \"'MSDOS/bcc/unzip_cr.prj.u'\" \(9233 characters\)
- sed "s/^X//" >'MSDOS/bcc/unzip_cr.prj.u' <<'END_OF_FILE'
- Xbegin 666 MSDOS/bcc/unzip_cr.prj
- XM5'5R8F\@0R!0<F]J96-T($9I;&4@&@ !#1(7 1H 0<R $ 'R0 " $ R@ "
- XM RP " $ S " $ S0 " ( S@ " SP " T " T0 "
- XMT@ " $ TP " $ U " , U@ " $ UP " $ \0 ! #R $ /, 0 !
- XM] ! 'U $ ?8 @ @/< 0 ^ ! #Y $ /H @ (+ $ @ OL
- XM 0 _ ! '] $ /X 0 _P ! 0$ 0$! 0 P$! $$ 0$ 4!
- XM 0 !@$! $' 0$ &0@! 0!D"0$! " * 0$ L! 0 # $! - 0$ X!
- XM 0 #P$! 0 0$ !$! 0 $@$! 3 0$ !0! 0 %0$! $6 0$ !<!
- XM @ @!@! 0 &0$" !&@$! ; 0$ !P! 0 !'0$! > 0$ Q\! 0 !
- XM( $! B 0$ ",! 0 ) $! E 0$ "8! @#_?R<! K 0( !9 @$
- XM 6L" 0 6@(! %; @$ 5P" 0 !70(! %> @$ 5\" 0 !8 (! %A @$
- XM 6(" 0 !8P(! %D @$ 64" 0 !9@(! %G @$ 6@" 0 :0(! %L @$
- XM 6T" 0 !;@(! %O @$ 7 " 0 !<0(! %R @$ 7," 0 != (! %U @$
- XM '8" 0 !=P(! %X @$ 7D" 0 !>@(! %[ @$ 7P" 0 C@(! %] @$
- XM 7X" 0 !?P(! & @$ 8$" 0 !@@(! @$ 80" 0 !A0(! && @$
- XM 8<" 0 !B (! &) @$ 8H" 0 !BP(! &, @$ 8T" 0 !CP(! &0 @$
- XM 9$" 0 !D@(! &3 @$ 2T!1
- XM "X!
- XM@ !#.EQ"3U),04Y$7$E.0TQ51$4
- XM
- XM "\!@ !#
- XM.EQ"3U),04Y$7$Q)0@
- XM
- XM # !! S,@
- XM,0$% #(U ,@$% #$P, ,P%_ $-265!4 "!#4EE05
- XM
- XM
- XM T 1X *@
- XM -0$> "H #8!'@ J
- XM W 1X *@
- XM . $> "H
- XM #D!'@ J Z 1X *@
- XM .P$> "H
- XM #P!'@ J
- XM ] 1X *@ /@$> "H
- XM #\!'@ J
- XM ! 8
- XM
- XM
- XM !$ 0@ ,S(W-C< !% 0@ .#$Y,@ !& 7\
- XM
- XM
- XM $,!!0 N0P /__
- XM S 8 0"/8V<8"@#5" !^1U)%4
- XM 9W)E<
- XM
- XM M;BL@)$U%32@V-"D@)$Y/4U=!4" D4%)/35!4("1#05 @35-'*$=215 R
- XM35-'*79O:60@*BYC(
- XM
- XM
- XM ,C_ 7Y4=7)B;R!!<W-E;6)L97(
- XM !405--
- XM
- XM "]-6" O6DD@+T\@)%1!4TT
- XM
- XM
- XM
- XM R?\ 5'5R8F\@?D1E8G5G
- XM9V5R '1D
- XM
- XM )$5814Y!344
- XM
- XM
- XM
- XM #*_P!4=7)B
- XM;R!^4')O9FEL97( ='!R;V8
- XM
- XM D15A%3D%-10
- XM
- XM
- XM
- XM
- XM ,O_ 5)^97-O=7)C92!#;VUP:6QE<@ !2
- XM0P
- XM "120P
- XM
- XM
- XM
- XM
- XM S/\!?DEM<&]R="!,:6)R87)I86X
- XM $E-4$Q)0@
- XM )$E-
- XM4$Q)0@
- XM
- XM
- XM
- XM #-____
- XM
- XM
- XM
- XM
- XM
- XM
- XM -0 Z! '@#28V<8$Q -.3
- XM "4! 54Y:25 N0P!53EI)4"Y#
- XM " ,
- XM! + C5F<8__________\ 1DE,15])3RY# $Q%7TE/+D,
- XM
- XM % 8 !P * ( H5F<89 ( )8 Y 0 34%0
- XM3D%-12Y# %!.04U%+D,
- XM + P #0 ) % L
- XM5F<82 ( !< #+ 34%40T@N0P!-051#2"Y#
- XM
- XM . \ $ ( %@ S5F<8P@0 $\$ "9 @ 34E30RY# %Q-25-#
- XM+D,
- XM 1 !( $P ' & X5F<88 4 !@&
- XM " 0 54Y)35!,3T0N0P!-4$Q/1"Y#
- XM 4 !4
- XM%@ & &@ ]5F<8H , "(# "^ 54Y214150T4N0P!%1%5#12Y#
- XM
- XM 7 !@ &0 % ' !$5F<8:@, @ "S 54Y3
- XM2%))3DLN0P!(4DE.2RY#
- XM : !L ' $
- XM __________\ 15A44D%#5"Y# %1204-4+D,
- XM
- XM = !X 'P # __________\ 0U)94%0N0P!#4EE0
- XM5"Y#
- XM * D " " " -@ >!2( #__Q$%
- XM! 7D!,0$I 2$!& $/009!/P#W0.] YP#>P-: _____\Z DL#U@$^ W(!,@,.
- XM 2(#J@ 2 T8 @.> O__1@ ! P!YMF88! EF&48!0 $! 7!@ $! 7
- XM!P $! 7" $! 7"0 $$T6"@ $! 7"P $! 7# $! 7#0 $! 7#@
- XM$! 7#P $! 7$ $! 7$0 $! 7__\ # 0 !\ <%R$%00 )9AE& 4
- XM ! 0%P8 ! 0%P< ! 0%P@ ! 0%PD !!-%@H ! 0%PL ! 0%PP ! 0
- XM%PT ! 0%PX ! 0%P\ ! 0%Q ! 0%Q$ ! 0%___3" @( $ = /:B
- XM8A<$ "6891@% 0$!<& 0$!<' 0$!<( 0$!<) 0318* 0$!<+
- XM 0$!<, 0$!<- 0$!<. 0$!</ 0$!<0 0$!<1 0$!?__TP@
- XM(" ! &P"EA4$8! EF&48!0 $! 7!@ $! 7!P $! 7" $! 7"0
- XM$$T6"@ $! 7"P $! 7# $! 7#0 $! 7#@ $! 7#P $! 7$ $! 7
- XM$0 $! 7__],(" @ 0 !D 3(YC& 0 )9AE& 4 ! 0%P8 ! 0%P< ! 0
- XM%P@ ! 0%PD !!-%@H ! 0%PL ! 0%PP ! 0%PT ! 0%PX ! 0%P\
- XM ! 0%Q ! 0%Q$ ! 0%___3" @( $ 7 &R.01@$ "6891@% 0$!<&
- XM 0$!<' 0$!<( 0$!<) 0318* 0$!<+ 0$!<, 0$!<- 0
- XM$!<. 0$!</ 0$!<0 0$!<1 0$!?__TP@(" ! %0#0?&48! E
- XMF&48!0 $! 7!@ $! 7!P $! 7" $! 7"0 $$T6"@ $! 7"P $! 7
- XM# $! 7#0 $! 7#@ $! 7#P $! 7$ $! 7$0 $! 7__],(" @____
- XM__]53E-(4DE.2RY# /______54Y214150T4N0P#______U5.24U03$]$+D,
- XM______]-25-#+D, ______]-051#2"Y# /______34%03D%-12Y# /______
- XM+BY<0D]23$%.1%Q)3D-,541%7$Q)34E44RY( /______+BY<0D]23$%.1%Q)
- XM3D-,541%7%-44DE.1RY( /______+BY<0D]23$%.1%Q)3D-,541%7%-41$Q)
- XM0BY( /______+BY<0D]23$%.1%Q)3D-,541%7$9#3E1,+D@ ______\N+EQ"
- XM3U),04Y$7$E.0TQ51$5<5$E-12Y( /______+BY<0D]23$%.1%Q)3D-,541%
- XM7$E/+D@ ______\N+EQ"3U),04Y$7$E.0TQ51$5<4UE37%1)345"+D@ ____
- XM__\N+EQ"3U),04Y$7$E.0TQ51$5<4UE37%-4050N2 #______RXN7$)/4DQ!
- XM3D1<24Y#3%5$15Q365-<5%E015,N2 #______RXN7$)/4DQ!3D1<24Y#3%5$
- XM15Q%4E).3RY( /______+BY<0D]23$%.1%Q)3D-,541%7$-465!%+D@ ____
- XM__\N+EQ"3U),04Y$7$E.0TQ51$5<7T1%1E,N2 #______RXN7$)/4DQ!3D1<
- XM24Y#3%5$15Q35$1)3RY( /______54Y:25 N2 #______U5.6DE0+D, -P!@
- XM " !? %X 70!< %L 6@!" $, 1 !9 %@ 5P!6 %4 5 !3 %( 40!0 $\
- XM3@!- $P 2P!* $D 2 !' $8 10!"
- X+ /__
- X
- Xend
- END_OF_FILE
- if test 9233 -ne `wc -c <'MSDOS/bcc/unzip_cr.prj.u'`; then
- echo shar: \"'MSDOS/bcc/unzip_cr.prj.u'\" unpacked with wrong size!
- else
- echo shar: Uudecoding \"'MSDOS/bcc/unzip_cr.prj.u'\"
- cat MSDOS/bcc/unzip_cr.prj.u | uudecode
- if [ -f MSDOS/bcc/unzip_cr.prj.u ]; then
- rm MSDOS/bcc/unzip_cr.prj.u
- fi
- fi
- # end of 'MSDOS/bcc/unzip_cr.prj.u'
- fi
- if test -f 'VMS/VMSmunch.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'VMS/VMSmunch.c'\"
- else
- echo shar: Extracting \"'VMS/VMSmunch.c'\" \(11678 characters\)
- sed "s/^X//" >'VMS/VMSmunch.c' <<'END_OF_FILE'
- X/*---------------------------------------------------------------------------
- X
- X VMSmunch.c version 1.1 7 Feb 1992
- X
- X This routine is a blatant and unrepentent appropriation of all the nasty
- X and difficult-to-do and complicated VMS shenanigans which Joe Meadows has
- X so magnificently captured in his FILE utility. Not only that, it's even
- X allowed! (see below). But let it be clear at the outset that Joe did all
- X the work; yea, verily, he is truly a godlike unit.
- X
- X The appropriations and modifications herein were performed primarily by
- X him known as "Cave Newt," although the Info-ZIP working group probably had
- X their fingers in it somewhere along the line. The idea is to put the raw
- X power of Joe's original routine at the disposal of various routines used
- X by UnZip (and Zip, possibly), not least among them the utime() function.
- X Read on for details...
- X
- X ---------------------------------------------------------------------------
- X
- X Usage (i.e., "interface," in geek-speak):
- X
- X int VMSmunch( char *filename, int action, char *ptr );
- X
- X filename the name of the file on which to be operated, obviously
- X action an integer which specifies what action to take
- X ptr pointer to any extra item which may be needed (else NULL)
- X
- X The possible values for the action argument are as follows:
- X
- X GET_TIMES get the creation and revision dates of filename; ptr
- X must point to an empty VMStimbuf struct, as defined below
- X (with room for at least 24 characters, including term.)
- X SET_TIMES set the creation and revision dates of filename (utime
- X option); ptr must point to a valid VMStimbuf struct,
- X as defined below
- X GET_RTYPE get the record type of filename; ptr must point to an
- X integer which, on return, is set to the type (as defined
- X in fatdef.h: FAT$C_* defines)
- X CHANGE_RTYPE change the record type to that specified by the integer
- X to which ptr points; save the old record type (later
- X saves overwrite earlier ones)
- X RESTORE_RTYPE restore the record type to the previously saved value;
- X or, if none, set it to "fixed-length, 512-byte" record
- X format (ptr not used)
- X
- X ---------------------------------------------------------------------------
- X
- X Comments from FILE.C, a utility to modify file characteristics:
- X
- X Written by Joe Meadows Jr, at the Fred Hutchinson Cancer Research Center
- X BITNET: JOE@FHCRCVAX
- X PHONE: (206) 467-4970
- X
- X There are no restrictions on this code, you may sell it, include it
- X with any commercial package, or feed it to a whale.. However, I would
- X appreciate it if you kept this comment in the source code so that anyone
- X receiving this code knows who to contact in case of problems. Note that
- X I do not demand this condition..
- X
- X ---------------------------------------------------------------------------*/
- X
- X
- X
- X
- X/*****************************/
- X/* Includes, Defines, etc. */
- X/*****************************/
- X
- X#include <descrip.h>
- X#include <rms.h>
- X#include <stdio.h>
- X#include <iodef.h>
- X#include <atrdef.h> /* this gets created with the c3.0 compiler */
- X#include <fibdef.h> /* this gets created with the c3.0 compiler */
- X
- X#include "fatdef.h"
- X#include "fchdef.h"
- X#include "fjndef.h"
- X
- X#include "VMSmunch.h" /* GET/SET_TIMES, RTYPE, etc. */
- X
- X#define RTYPE fat$r_rtype_overlay.fat$r_rtype_bits
- X#define RATTRIB fat$r_rattrib_overlay.fat$r_rattrib_bits
- X
- Xstatic void asctim();
- Xstatic void bintim();
- X
- Xstruct VMStimbuf { /* VMSmunch */
- X char *actime; /* VMS revision date, ASCII format */
- X char *modtime; /* VMS creation date, ASCII format */
- X};
- X
- X/* from <ssdef.h> */
- X#ifndef SS$_NORMAL
- X# define SS$_NORMAL 1
- X# define SS$_BADPARAM 20
- X#endif
- X
- X
- X
- X
- X
- X/*************************/
- X/* Function VMSmunch() */
- X/*************************/
- X
- Xint VMSmunch( filename, action, ptr )
- X char *filename, *ptr;
- X int action;
- X{
- X
- X /* original file.c variables */
- X
- X static struct FAB Fab;
- X static struct NAM Nam;
- X static struct fibdef Fib; /* short fib */
- X
- X static struct dsc$descriptor FibDesc =
- X {sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,&Fib};
- X static struct dsc$descriptor_s DevDesc =
- X {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.nam$t_dvi[1]};
- X static struct fatdef Fat;
- X static union {
- X struct fchdef fch;
- X long int dummy;
- X } uchar;
- X static struct fjndef jnl;
- X static long int Cdate[2],Rdate[2],Edate[2],Bdate[2];
- X static short int revisions;
- X static unsigned long uic;
- X static union {
- X unsigned short int value;
- X struct {
- X unsigned system : 4;
- X unsigned owner : 4;
- X unsigned group : 4;
- X unsigned world : 4;
- X } bits;
- X } prot;
- X
- X static struct atrdef Atr[] = {
- X {sizeof(Fat),ATR$C_RECATTR,&Fat}, /* record attributes */
- X {sizeof(uchar),ATR$C_UCHAR,&uchar}, /* File characteristics */
- X {sizeof(Cdate),ATR$C_CREDATE,&Cdate[0]}, /* Creation date */
- X {sizeof(Rdate),ATR$C_REVDATE,&Rdate[0]}, /* Revision date */
- X {sizeof(Edate),ATR$C_EXPDATE,&Edate[0]}, /* Expiration date */
- X {sizeof(Bdate),ATR$C_BAKDATE,&Bdate[0]}, /* Backup date */
- X {sizeof(revisions),ATR$C_ASCDATES,&revisions}, /* number of revisions */
- X {sizeof(prot),ATR$C_FPRO,&prot}, /* file protection */
- X {sizeof(uic),ATR$C_UIC,&uic}, /* file owner */
- X {sizeof(jnl),ATR$C_JOURNAL,&jnl}, /* journal flags */
- X {0,0,0}
- X } ;
- X
- X static char EName[NAM$C_MAXRSS];
- X static char RName[NAM$C_MAXRSS];
- X static struct dsc$descriptor_s FileName =
- X {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
- X static struct dsc$descriptor_s string = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
- X static short int DevChan;
- X static short int iosb[4];
- X
- X static long int i,status;
- X/* static char *retval; */
- X
- X
- X /* new VMSmunch variables */
- X
- X static int old_rtype=FAT$C_FIXED; /* storage for record type */
- X
- X
- X
- X/*---------------------------------------------------------------------------
- X Initialize attribute blocks, parse filename, resolve any wildcards, and
- X get the file info.
- X ---------------------------------------------------------------------------*/
- X
- X /* initialize RMS structures, we need a NAM to retrieve the FID */
- X Fab = cc$rms_fab;
- X Fab.fab$l_fna = filename;
- X Fab.fab$b_fns = strlen(filename);
- X Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */
- X Nam = cc$rms_nam;
- X Nam.nam$l_esa = &EName; /* expanded filename */
- X Nam.nam$b_ess = sizeof(EName);
- X Nam.nam$l_rsa = &RName; /* resultant filename */
- X Nam.nam$b_rss = sizeof(RName);
- X
- X /* do $PARSE and $SEARCH here */
- X status = sys$parse(&Fab);
- X if (!(status & 1)) return(status);
- X
- X /* search for the first file.. If none signal error */
- X status = sys$search(&Fab);
- X if (!(status & 1)) return(status);
- X
- X while (status & 1) {
- X /* initialize Device name length, note that this points into the NAM
- X to get the device name filled in by the $PARSE, $SEARCH services */
- X DevDesc.dsc$w_length = Nam.nam$t_dvi[0];
- X
- X status = sys$assign(&DevDesc,&DevChan,0,0);
- X if (!(status & 1)) return(status);
- X
- X FileName.dsc$a_pointer = Nam.nam$l_name;
- X FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver;
- X
- X /* Initialize the FIB */
- X for (i=0;i<3;i++)
- X Fib.fib$r_fid_overlay.fib$w_fid[i]=Nam.nam$w_fid[i];
- X for (i=0;i<3;i++)
- X Fib.fib$r_did_overlay.fib$w_did[i]=Nam.nam$w_did[i];
- X
- X /* Use the IO$_ACCESS function to return info about the file */
- X /* Note, used this way, the file is not opened, and the expiration */
- X /* and revision dates are not modified */
- X status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0,
- X &FibDesc,&FileName,0,0,&Atr,0);
- X if (!(status & 1)) return(status);
- X status = iosb[0];
- X if (!(status & 1)) return(status);
- X
- X /*-----------------------------------------------------------------------
- X We have the current information from the file: now see what user
- X wants done with it.
- X -----------------------------------------------------------------------*/
- X
- X switch (action) {
- X
- X case GET_TIMES:
- X asctim(((struct VMStimbuf *)ptr)->modtime, Cdate);
- X asctim(((struct VMStimbuf *)ptr)->actime, Rdate);
- X break;
- X
- X case SET_TIMES:
- X bintim(((struct VMStimbuf *)ptr)->modtime, Cdate);
- X bintim(((struct VMStimbuf *)ptr)->actime, Rdate);
- X break;
- X
- X case GET_RTYPE: /* non-modifying */
- X *(int *)ptr = Fat.RTYPE.fat$v_rtype;
- X return RMS$_NORMAL; /* return to user */
- X break;
- X
- X case CHANGE_RTYPE:
- X old_rtype = Fat.RTYPE.fat$v_rtype; /* save current one */
- X if ((*(int *)ptr < FAT$C_UNDEFINED) ||
- X (*(int *)ptr > FAT$C_STREAMCR))
- X Fat.RTYPE.fat$v_rtype = FAT$C_STREAMLF; /* Unix I/O happy */
- X else
- X Fat.RTYPE.fat$v_rtype = *(int *)ptr;
- X break;
- X
- X case RESTORE_RTYPE:
- X Fat.RTYPE.fat$v_rtype = old_rtype;
- X break;
- X
- X default:
- X return SS$_BADPARAM; /* anything better? */
- X }
- X
- X /*-----------------------------------------------------------------------
- X Go back and write modified data to the file header.
- X -----------------------------------------------------------------------*/
- X
- X /* note, part of the FIB was cleared by earlier QIOW, so reset it */
- X Fib.fib$r_acctl_overlay.fib$l_acctl = FIB$M_NORECORD;
- X for (i=0;i<3;i++)
- X Fib.fib$r_fid_overlay.fib$w_fid[i]=Nam.nam$w_fid[i];
- X for (i=0;i<3;i++)
- X Fib.fib$r_did_overlay.fib$w_did[i]=Nam.nam$w_did[i];
- X
- X /* Use the IO$_MODIFY function to change info about the file */
- X /* Note, used this way, the file is not opened, however this would */
- X /* normally cause the expiration and revision dates to be modified. */
- X /* Using FIB$M_NORECORD prohibits this from happening. */
- X status = sys$qiow(0,DevChan,IO$_MODIFY,&iosb,0,0,
- X &FibDesc,&FileName,0,0,&Atr,0);
- X if (!(status & 1)) return(status);
- X
- X status = iosb[0];
- X if (!(status & 1)) return(status);
- X
- X status = sys$dassgn(DevChan);
- X if (!(status & 1)) return(status);
- X
- X /* look for next file, if none, no big deal.. */
- X status = sys$search(&Fab);
- X }
- X} /* end function VMSmunch() */
- X
- X
- X
- X
- X
- X/***********************/
- X/* Function bintim() */
- X/***********************/
- X
- Xvoid asctim(time,binval) /* convert 64-bit binval to string, put in time */
- X char *time;
- X long int binval[2];
- X{
- X static struct dsc$descriptor date_str={23,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
- X /* dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer */
- X
- X date_str.dsc$a_pointer = time;
- X sys$asctim(0, &date_str, binval, 0);
- X time[23] = '\0';
- X}
- X
- X
- X
- X
- X
- X/***********************/
- X/* Function bintim() */
- X/***********************/
- X
- Xvoid bintim(time,binval) /* convert time string to 64 bits, put in binval */
- X char *time;
- X long int binval[2];
- X{
- X static struct dsc$descriptor date_str={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
- X
- X date_str.dsc$w_length = strlen(time);
- X date_str.dsc$a_pointer = time;
- X sys$bintim(&date_str, binval);
- X}
- END_OF_FILE
- if test 11678 -ne `wc -c <'VMS/VMSmunch.c'`; then
- echo shar: \"'VMS/VMSmunch.c'\" unpacked with wrong size!
- fi
- # end of 'VMS/VMSmunch.c'
- fi
- if test -f 'VMS/vms.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'VMS/vms.c'\"
- else
- echo shar: Extracting \"'VMS/vms.c'\" \(20178 characters\)
- sed "s/^X//" >'VMS/vms.c' <<'END_OF_FILE'
- X/*************************************************************************
- X * *
- X * Copyright (C) 1992 Igor Mandrichenko. *
- X * Permission is granted to any individual or institution to use, copy, *
- X * or redistribute this software so long as all of the original files *
- X * are included unmodified, that it is not sold for profit, and that *
- X * this copyright notice is retained. *
- X * *
- X *************************************************************************/
- X
- X/*
- X * vms.c by Igor Mandrichenko
- X * version 1.1-2
- X *
- X * This module contains routines to extract VMS file attributes
- X * from extra field and create file with these attributes. This
- X * source is mainly based on sources of file_io.c from UNZIP 4.1
- X * by Info-ZIP. [Info-ZIP note: very little of this code is from
- X * file_io.c; it has virtually been written from the ground up.
- X * Of the few lines which are from the older code, most are mine
- X * (G. Roelofs) and I make no claims upon them. On the contrary,
- X * my/our thanks to Igor for his contributions!]
- X */
- X
- X/*
- X * Revision history:
- X * 1.0-1 Mandrichenko 16-feb-1992
- X * Recognize -c option
- X * 1.0-2 Mandrichenko 17-feb-1992
- X * Do not use ASYnchroneous mode.
- X * 1.0-3 Mandrichenko 2-mar-1992
- X * Make code more standard
- X * Use lrec instead of crec -- unzip4.2p do not provide
- X * crec now.
- X * 1.1 Mandrichenko 5-mar-1992
- X * Make use of asynchronous output.
- X * Be ready to extract RMS blocks of invalid size (because diff
- X * VMS version used to compress).
- X * 1.1-1 Mandrichenko 11-mar-1992
- X * Use internal file attributes saved in pInfo to decide
- X * if the file is text. [GRR: temporarily disabled, since
- X * no way to override and force binary extraction]
- X * 1.1-2 Mandrichenko 13-mar-1992
- X * Do not restore owner/protection info if -X not specified.
- X */
- X
- X#ifdef VMS /* VMS only ! */
- X
- X/************************************/
- X/* File_IO Includes, Defines, etc. */
- X/************************************/
- X
- X#ifdef VAXC
- X#include rms
- X#include descrip
- X#include syidef
- X#else
- X#include <rms.h>
- X#include <descrip.h>
- X#include <syidef.h>
- X#endif
- X
- X#include "unzip.h"
- X
- X#define ERR(s) !((s) & 1)
- X
- X#define BUFS512 8192*2 /* Must be a multiple of 512 */
- X
- Xstatic int WriteBuffer __((int fd, unsigned char *buf, int len));
- Xstatic int _flush_blocks __((void));
- Xstatic int _flush_records __((void));
- Xstatic byte *extract_block __((byte *));
- X
- X/*
- X* Local static storage
- X*/
- Xstatic struct FAB *outfab = 0;
- Xstatic struct RAB *outrab = 0;
- Xstatic struct FAB fileblk;
- Xstatic struct XABFHC *xabfhc = 0;
- Xstatic struct XABDAT dattim, *xabdat = 0;
- Xstatic struct XABRDT *xabrdt = 0;
- Xstatic struct XABPRO *xabpro = 0;
- Xstatic struct XABKEY *xabkey = 0;
- Xstatic struct XABALL *xaball = 0;
- Xstatic struct RAB rab;
- X
- Xstatic int text_file = 0;
- X
- Xstatic char locbuf[BUFS512];
- Xstatic int loccnt = 0;
- Xstatic char *locptr;
- X
- X
- Xstruct bufdsc
- X{ struct bufdsc *next;
- X byte *buf;
- X int bufcnt;
- X};
- X
- Xstatic struct bufdsc b1,b2,*curbuf;
- Xstatic byte buf1[BUFS512],buf2[BUFS512];
- X
- Xint create_output_file()
- X{ /* return non-0 if sys$create failed */
- X int ierr, yr, mo, dy, hh, mm, ss;
- X char timbuf[24]; /* length = first entry in "stupid" + 1 */
- X int attr_given = 0; /* =1 if VMS attributes are present in
- X * extra_field */
- X
- X rab = cc$rms_rab; /* fill FAB & RAB with default values */
- X fileblk = cc$rms_fab;
- X
- X text_file = /* pInfo->text || */ aflag || cflag;
- X
- X if (attr_given = find_vms_attrs())
- X { text_file = 0;
- X if( cflag )
- X { printf("Can not put VMS file %s to stdout.\n",
- X filename);
- X return 50;
- X }
- X }
- X
- X if (!attr_given)
- X {
- X outfab = &fileblk;
- X outfab->fab$l_xab = 0L;
- X if (text_file)
- X {
- X outfab->fab$b_rfm = FAB$C_VAR; /* variable length records */
- X outfab->fab$b_rat = FAB$M_CR; /* carriage-return carriage ctrl */
- X }
- X else
- X {
- X outfab->fab$b_rfm = FAB$C_STMLF; /* stream-LF record format */
- X outfab->fab$b_rat = FAB$M_CR; /* carriage-return carriage ctrl */
- X }
- X }
- X
- X if(!cflag)
- X outfab->fab$l_fna = filename;
- X else
- X outfab->fab$l_fna = "sys$output:";
- X
- X outfab->fab$b_fns = strlen(outfab->fab$l_fna);
- X
- X if (!attr_given || xabdat == 0)
- X {
- X static char *month[] =
- X {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
- X "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
- X /* fixed-length string descriptor (why not just a pointer to timbuf? sigh.) */
- X struct dsc$descriptor stupid =
- X {23, DSC$K_DTYPE_T, DSC$K_CLASS_S, timbuf};
- X
- X yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + 1980; /* dissect date */
- X mo = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1;
- X dy = (lrec.last_mod_file_date & 0x1f);
- X hh = (lrec.last_mod_file_time >> 11) & 0x1f; /* dissect time */
- X mm = (lrec.last_mod_file_time >> 5) & 0x3f;
- X ss = (lrec.last_mod_file_time & 0x1f) * 2;
- X
- X dattim = cc$rms_xabdat; /* fill XAB with default values */
- X dattim.xab$l_nxt = outfab->fab$l_xab;
- X outfab->fab$l_xab = (char*)(xabdat = &dattim);
- X
- X sprintf(timbuf, "%02d-%3s-%04d %02d:%02d:%02d.00", dy, month[mo], yr,
- X hh, mm, ss);
- X sys$bintim(&stupid, &dattim.xab$q_cdt);
- X }
- X
- X#ifdef DEBUG
- X printf("XAB chain before CREATE dump:\n");
- X dump_rms_block(outfab);
- X {
- X struct XABALL *x;
- X for (x = outfab->fab$l_xab; x != 0L; x = x->xab$l_nxt)
- X dump_rms_block(x);
- X }
- X#endif
- X
- X outfab->fab$w_ifi = 0; /* Clear IFI. It may be nonzero after ZIP */
- X
- X if ((ierr = sys$create(outfab)) != RMS$_NORMAL)
- X {
- X message("[ can not create output file ]\n", ierr);
- X message("", outfab->fab$l_stv);
- X fprintf(stderr, "Can't create output file: %s\n", filename);
- X return (1);
- X }
- X
- X if (!text_file && !cflag) /* Do not reopen text files and stdout
- X * Just open them in right mode */
- X {
- X /*
- X * Reopen file for Block I/O with no XABs.
- X */
- X if ((ierr = sys$close(outfab)) != RMS$_NORMAL)
- X {
- X#ifdef DEBUG
- X message("[ create_output_file: sys$close failed ]\n", ierr);
- X message("", outfab->fab$l_stv);
- X#endif
- X fprintf(stderr, "Can't create output file: %s\n", filename);
- X return (1);
- X }
- X
- X
- X outfab->fab$b_fac = FAB$M_BIO | FAB$M_PUT; /* Get ready for block
- X * output */
- X outfab->fab$l_xab = 0L; /* Unlink all XABs */
- X
- X if ((ierr = sys$open(outfab)) != RMS$_NORMAL)
- X {
- X message("[ Can not open output file ]\n", ierr);
- X message("", outfab->fab$l_stv);
- X return (1);
- X }
- X }
- X
- X outrab = &rab;
- X rab.rab$l_fab = outfab;
- X if( !text_file ) rab.rab$l_rop |= RAB$M_BIO;
- X if( !text_file ) rab.rab$l_rop |= RAB$M_ASY;
- X rab.rab$b_rac = RAB$C_SEQ;
- X
- X if ((ierr = sys$connect(outrab)) != RMS$_NORMAL)
- X {
- X#ifdef DEBUG
- X fprintf(stderr, "create_output_file: sys$connect failed on file %s\n",
- X filename);
- X fprintf(stderr, " status = %d\n", ierr);
- X fprintf(stderr, " fab.sts = %d\n", outfab->fab$l_sts);
- X fprintf(stderr, " fab.stv = %d\n", outfab->fab$l_stv);
- X#endif
- X fprintf(stderr, "Can't create output file: %s\n", filename);
- X return (1);
- X }
- X
- X locptr = &locbuf[0];
- X loccnt = 0;
- X
- X b1.buf = &buf1[0];
- X b1.bufcnt = 0;
- X b1.next = &b2;
- X b2.buf = &buf2[0];
- X b2.bufcnt = 0;
- X b2.next = &b1;
- X curbuf = &b1;
- X
- X return (0);
- X}
- X
- X/*
- X* Extra record format
- X* ===================
- X* signature (2 bytes) = 'I','M'
- X* size (2 bytes)
- X* block signature (4 bytes)
- X* flags (2 bytes)
- X* uncomprssed size(2 bytes)
- X* reserved (4 bytes)
- X* data ((size-12) bytes)
- X* ....
- X*/
- X
- Xstruct extra_block
- X{
- X UWORD sig; /* Extra field block header structure */
- X UWORD size;
- X ULONG bid;
- X UWORD flags;
- X UWORD length;
- X ULONG reserved;
- X byte body[1];
- X};
- X
- X/*
- X * Extra field signature and block signatures
- X */
- X
- X#define SIGNATURE "IM"
- X#define FABL (cc$rms_fab.fab$b_bln)
- X#define RABL (cc$rms_rab.rab$b_bln)
- X#define XALLL (cc$rms_xaball.xab$b_bln)
- X#define XDATL (cc$rms_xabdat.xab$b_bln)
- X#define XFHCL (cc$rms_xabfhc.xab$b_bln)
- X#define XKEYL (cc$rms_xabkey.xab$b_bln)
- X#define XPROL (cc$rms_xabpro.xab$b_bln)
- X#define XRDTL (cc$rms_xabrdt.xab$b_bln)
- X#define XSUML (cc$rms_xabsum.xab$b_bln)
- X#define EXTBSL 4 /* Block signature length */
- X#define RESL 8 /* Rserved 8 bytes */
- X#define EXTHL (4+EXTBSL)
- X#define FABSIG "VFAB"
- X#define XALLSIG "VALL"
- X#define XFHCSIG "VFHC"
- X#define XDATSIG "VDAT"
- X#define XRDTSIG "VRDT"
- X#define XPROSIG "VPRO"
- X#define XKEYSIG "VKEY"
- X#define XNAMSIG "VNAM"
- X#define VERSIG "VMSV"
- X
- X
- X
- X#define W(p) (*(unsigned short*)(p))
- X#define L(p) (*(unsigned long*)(p))
- X#define EQL_L(a,b) ( L(a) == L(b) )
- X#define EQL_W(a,b) ( W(a) == W(b) )
- X
- X/****************************************************************
- X * Function find_vms_attrs scans ZIP entry extra field if any *
- X * and looks for VMS attribute records. Returns 0 if either no *
- X * attributes found or no fab given. *
- X ****************************************************************/
- Xint find_vms_attrs()
- X{
- X byte *scan = extra_field;
- X struct extra_block *blk;
- X struct XABALL *first_xab = 0L, *last_xab = 0L;
- X int len;
- X
- X outfab = xabfhc = xabdat = xabrdt = xabpro = 0L;
- X
- X if (scan == NULL)
- X return 0;
- X/*
- X if (crec.extra_field_length)
- X len = crec.extra_field_length;
- X else
- X*/
- X len = lrec.extra_field_length;
- X
- X#define LINK(p) { \
- X if( first_xab == 0L ) \
- X first_xab = p; \
- X if( last_xab != 0L ) \
- X last_xab -> xab$l_nxt = p; \
- X last_xab = p; \
- X p -> xab$l_nxt = 0; \
- X }
- X /* End of macro LINK */
- X
- X while (len > 0)
- X {
- X blk = (struct block *)scan;
- X if (EQL_W(&blk->sig, SIGNATURE))
- X {
- X byte *block_id;
- X block_id = &blk->bid;
- X if (EQL_L(block_id, FABSIG))
- X {
- X outfab = (struct FAB *) extract_block(blk, 0,
- X &cc$rms_fab, FABL);
- X }
- X else if (EQL_L(block_id, XALLSIG))
- X {
- X xaball = (struct XABALL *) extract_block(blk, 0,
- X &cc$rms_xaball, XALLL);
- X LINK(xaball);
- X }
- X else if (EQL_L(block_id, XKEYSIG))
- X {
- X xabkey = (struct XABKEY *) extract_block(blk, 0,
- X &cc$rms_xabkey, XKEYL);
- X LINK(xabkey);
- X }
- X else if (EQL_L(block_id, XFHCSIG))
- X {
- X xabfhc = (struct XABFHC *) extract_block(blk, 0,
- X &cc$rms_xabfhc, XFHCL);
- X LINK(xabfhc);
- X }
- X else if (EQL_L(block_id, XDATSIG))
- X {
- X xabdat = (struct XABDAT *) extract_block(blk, 0,
- X &cc$rms_xabdat, XDATL);
- X LINK(xabdat);
- X }
- X else if (EQL_L(block_id, XRDTSIG))
- X {
- X xabrdt = (struct XABRDT *) extract_block(blk, 0,
- X &cc$rms_xabrdt, XRDTL);
- X /* LINK(xabrdt); -- Do not link xabrdt */
- X }
- X else if (EQL_L(block_id, XPROSIG))
- X {
- X xabpro = (struct XABPRO *) extract_block(blk, 0,
- X &cc$rms_xabpro, XPROL);
- X /* LINK(xabpro); -- Do not link xabpro
- X until close */
- X }
- X else if (EQL_L(block_id, VERSIG))
- X {
- X char verbuf[80];
- X int verlen = 0;
- X int vl = 0;
- X int item = SYI$_VERSION;
- X $DESCRIPTOR(version, verbuf);
- X byte *vers;
- X
- X lib$getsyi(&item, 0, &version, &verlen, 0, 0);
- X verbuf[verlen] = 0;
- X vers = extract_block(blk, &vl, 0, 0);
- X if (strncmp(verbuf, vers, verlen))
- X {
- X printf("[ Warning: VMS version mismatch.");
- X
- X printf(" This version %s --", verbuf);
- X strncpy(verbuf, vers, vl);
- X verbuf[vl] = 0;
- X printf(" version made by %s ]\n", verbuf);
- X }
- X free(vers);
- X }
- X else
- X fprintf(stderr, "[ Warning: Unknown block signature %s ]\n",
- X block_id);
- X }
- X len -= blk->size + 4;
- X scan += blk->size + 4;
- X }
- X if (outfab != 0)
- X {
- X outfab->fab$l_xab = first_xab;
- X return 1;
- X }
- X else
- X return 0;
- X}
- X
- X/******************************
- X * Function extract_block *
- X ******************************/
- X/*
- X * Simple uncompression routne. The compression uses bit stream.
- X * Compression scheme:
- X *
- X * if(byte!=0)
- X * putbit(1),putyte(byte)
- X * else
- X * putbit(0)
- X */
- Xstatic byte *extract_block(p, retlen, init, needlen)
- X int *retlen;
- Xstruct extra_block *p;
- Xbyte *init;
- Xint needlen;
- X{
- X byte *block; /* Pointer to block allocated */
- X byte *bitptr; /* Pointer into compressed data */
- X byte *outptr; /* Pointer into output block */
- X UWORD length;
- X ULONG bitbuf = 0;
- X int bitcnt = 0;
- X
- X#define _FILL if(bitcnt+8 <= 32) \
- X { bitbuf |= (*bitptr++) << bitcnt;\
- X bitcnt += 8; \
- X }
- X
- X
- X if( p->flags & 1 )
- X length = p->length; /* Block is compressed */
- X else
- X length = p->size - EXTBSL - RESL; /* Simple case, uncompressed */
- X
- X if( needlen == 0 )
- X needlen = length;
- X
- X if(retlen)
- X *retlen = needlen;
- X
- X if( (p->flags & 1) || (needlen > length) )
- X { if ((block = (byte*)malloc(needlen)) == NULL)
- X return NULL;
- X }
- X/*
- X else if( needlen > length )
- X { if ((block = (byte*)malloc(needlen)) == NULL)
- X return NULL;
- X }
- X*/
- X else outptr = block = &p->body[0];
- X
- X if(init && (length < needlen))
- X memcpy(block,init,needlen);
- X
- X if ((p->flags & 1) == 0)
- X return block; /* Do nothing more if uncompressed */
- X
- X outptr = block;
- X bitptr = &p->body[0];
- X
- X if(length > needlen)
- X length = needlen;
- X
- X while (length--)
- X {
- X if (bitcnt <= 0)
- X _FILL;
- X
- X if (bitbuf & 1)
- X {
- X bitbuf >>= 1;
- X if ((bitcnt -= 1) < 8)
- X _FILL;
- X *outptr++ = (byte) bitbuf;
- X bitcnt -= 8;
- X bitbuf >>= 8;
- X }
- X else
- X {
- X *outptr++ = 0;
- X bitcnt -= 1;
- X bitbuf >>= 1;
- X }
- X }
- X return block;
- X}
- X
- X/***************************/
- X/* Function FlushOutput() */
- X/***************************/
- X
- Xint FlushOutput()
- X{ /* return PK-type error code */
- X /* flush contents of output buffer */
- X if (tflag)
- X { /* Do not output. Update CRC only */
- X UpdateCRC(outbuf, outcnt);
- X outpos += outcnt;
- X outcnt = 0;
- X outptr = outbuf;
- X return 0;
- X }
- X else
- X return text_file ? _flush_records(0) : _flush_blocks(0);
- X}
- X
- Xstatic int _flush_blocks(final_flag) /* Asynchronous version */
- X int final_flag;
- X/* 1 if this is the final flushout */
- X{
- X int round;
- X int rest;
- X int off = 0;
- X int out_count = outcnt;
- X int status;
- X
- X while(out_count > 0)
- X { if( curbuf -> bufcnt < BUFS512 )
- X { int ncpy;
- X ncpy = out_count > (BUFS512-curbuf->bufcnt) ?
- X BUFS512-curbuf->bufcnt :
- X out_count;
- X memcpy(curbuf->buf + curbuf->bufcnt, outbuf+off, ncpy);
- X out_count -= ncpy;
- X curbuf -> bufcnt += ncpy;
- X off += ncpy;
- X }
- X if( curbuf -> bufcnt == BUFS512 )
- X {
- X status = WriteBuffer(curbuf->buf,curbuf->bufcnt);
- X if(status)
- X return status;
- X curbuf = curbuf -> next;
- X curbuf -> bufcnt = 0;
- X }
- X }
- X
- X UpdateCRC(outbuf, outcnt);
- X outpos += outcnt;
- X outcnt = 0;
- X outptr = outbuf;
- X
- X return (final_flag && (curbuf->bufcnt > 0)) ?
- X WriteBuffer(curbuf->buf,curbuf->bufcnt) :
- X 0; /* 0: no error */
- X}
- X
- X#define RECORD_END(c) ((c) == CR || (c) == LF)
- X
- Xstatic int _flush_records(final_flag)
- X int final_flag;
- X/* 1 if this is the final flushout */
- X{
- X int rest;
- X int end = 0, start = 0;
- X int off = 0;
- X
- X if (outcnt == 0 && loccnt == 0)
- X return 0; /* Nothing to do ... */
- X
- X if (loccnt)
- X {
- X for (end = 0; end < outcnt && !RECORD_END(outbuf[end]);)
- X ++end;
- X if (end >= outcnt)
- X {
- X fprintf(stderr, "[ Warning: Record too long (%d) ]\n",
- X outcnt + loccnt);
- X if (WriteRecord(locbuf, loccnt))
- X return (50);
- X memcpy(locbuf, outbuf, outcnt);
- X locptr = &locbuf[loccnt = outcnt];
- X }
- X else
- X {
- X memcpy(locptr, outbuf, end);
- X if (WriteRecord(locbuf, loccnt + end))
- X return (50);
- X loccnt = 0;
- X locptr = &locbuf;
- X }
- X start = end + 1;
- X }
- X
- X do
- X {
- X while (start < outcnt && outbuf[start] == CR) /* Skip CR's at the
- X * beginning of rec. */
- X ++start;
- X /* Find record end */
- X for (end = start; end < outcnt && !RECORD_END(outbuf[end]);)
- X ++end;
- X
- X if (end < outcnt)
- X { /* Record end found, write the record */
- X if (WriteRecord(outbuf + start, end - start))
- X return (50);
- X /* Shift to the begining of the next record */
- X start = end + 1;
- X }
- X } while (start < outcnt && end < outcnt);
- X
- X rest = outcnt - start;
- X
- X if (rest > 0)
- X if (final_flag)
- X {
- X /* This is a final flush. Put out all remaining in
- X * the buffer */
- X if (loccnt && WriteRecord(locbuf, loccnt))
- X return (50);
- X }
- X else
- X {
- X memcpy(locptr, outbuf + start, rest);
- X locptr += rest;
- X loccnt += rest;
- X }
- X UpdateCRC(outbuf, outcnt);
- X outpos += outcnt;
- X outcnt = 0;
- X outptr = outbuf;
- X return (0); /* 0: no error */
- X}
- X
- X/***************************/
- X/* Function WriteBuffer() */
- X/***************************/
- X
- Xstatic int WriteBuffer(buf, len)/* return 0 if successful, 1 if not */
- X unsigned char *buf;
- Xint len;
- X{
- X int status;
- X
- X status = sys$wait(outrab);
- X#ifdef DEBUG
- X if(ERR(status))
- X { message("[ Write buffer: sys$wait faled ]\n",status);
- X message("",outrab->rab$l_sts);
- X message("",outrab->rab$l_sts);
- X }
- X#endif
- X outrab->rab$w_rsz = len;
- X outrab->rab$l_rbf = buf;
- X
- X if (ERR(status = sys$write(outrab)))
- X {
- X fprintf(stderr, "WriteBuffer: sys$write failed.\n",
- X filename);
- X fprintf(stderr, " status = %d\n", status);
- X fprintf(stderr, " rab->sts = %d\n", outrab->rab$l_sts);
- X fprintf(stderr, " stv = %d\n", outrab->rab$l_stv);
- X return 50;
- X }
- X return (0);
- X}
- X
- X/***************************/
- X/* Function WriteRecord() */
- X/***************************/
- X
- Xstatic int WriteRecord(rec, len)/* return 0 if successful, 1 if not */
- X unsigned char *rec;
- Xint len;
- X{
- X int status;
- X
- X sys$wait(outrab);
- X#ifdef DEBUG
- X if(ERR(status))
- X { message("[ Write buffer: sys$wait faled ]\n",status);
- X message("",outrab->rab$l_sts);
- X message("",outrab->rab$l_sts);
- X }
- X#endif
- X outrab->rab$w_rsz = len;
- X outrab->rab$l_rbf = rec;
- X
- X if (ERR(status = sys$put(outrab)))
- X {
- X fprintf(stderr, "WriteRecord: sys$put failed.\n",
- X filename);
- X fprintf(stderr, " status = %d\n", status);
- X fprintf(stderr, " rab->sts = %d\n", outrab->rab$l_sts);
- X fprintf(stderr, " stv = %d\n", outrab->rab$l_stv);
- X return 50;
- X }
- X return (0);
- X}
- X
- X/********************************/
- X/* Function CloseOutputFile() */
- X/********************************/
- X
- Xint CloseOutputFile()
- X{
- X int status;
- X
- X if (text_file) _flush_records(1);
- X else
- X _flush_blocks(1);
- X
- X if ((outfab->fab$l_xab = xabrdt) != 0L) /* Link XABPRO and XABRDT */
- X xabrdt->xab$l_nxt = (secinf ? xabpro : 0L);
- X else
- X outfab->fab$l_xab = (secinf ? xabpro : 0L);
- X
- X sys$wait(outrab);
- X
- X status = sys$close(outfab);
- X#ifdef DEBUG
- X if (ERR(status))
- X {
- X message("\r[ Warning: can not set owner/protection/time attributes ]\n", status);
- X message("", outfab->fab$l_stv);
- X }
- X#endif
- X}
- X
- X#ifdef DEBUG
- Xdump_rms_block(p)
- X unsigned char *p;
- X{
- X unsigned char bid, len;
- X int err;
- X char *type;
- X char buf[132];
- X int i;
- X
- X err = 0;
- X bid = p[0];
- X len = p[1];
- X switch (bid)
- X {
- X case FAB$C_BID:
- X type = "FAB";
- X break;
- X case XAB$C_ALL:
- X type = "xabALL";
- X break;
- X case XAB$C_KEY:
- X type = "xabKEY";
- X break;
- X case XAB$C_DAT:
- X type = "xabDAT";
- X break;
- X case XAB$C_RDT:
- X type = "xabRDT";
- X break;
- X case XAB$C_FHC:
- X type = "xabFHC";
- X break;
- X case XAB$C_PRO:
- X type = "xabPRO";
- X break;
- X default:
- X type = "Unknown";
- X err = 1;
- X break;
- X }
- X printf("Block @%08X of type %s (%d).", p, type, bid);
- X if (err)
- X {
- X printf("\n");
- X return;
- X }
- X printf(" Size = %d\n", len);
- X printf(" Offset - Hex - Dec\n");
- X for (i = 0; i < len; i += 8)
- X {
- X int j;
- X printf("%3d - ", i);
- X for (j = 0; j < 8; j++)
- X if (i + j < len)
- X printf("%02X ", p[i + j]);
- X else
- X printf(" ");
- X printf(" - ");
- X for (j = 0; j < 8; j++)
- X if (i + j < len)
- X printf("%03d ", p[i + j]);
- X else
- X printf(" ");
- X printf("\n");
- X }
- X}
- X
- X#endif /* DEBUG */
- X
- Xmessage(string, status)
- X int status;
- Xchar *string;
- X{
- X char msgbuf[256];
- X $DESCRIPTOR(msgd, msgbuf);
- X int msglen = 0;
- X
- X if (ERR(lib$sys_getmsg(&status, &msglen, &msgd, 0, 0)))
- X fprintf(stderr, "%s[ VMS status = %d ]\n", string, status);
- X else
- X {
- X msgbuf[msglen] = 0;
- X fprintf(stderr, "%s[ %s ]\n", string, msgbuf);
- X }
- X}
- X
- X
- X#endif /* !VMS */
- END_OF_FILE
- if test 20178 -ne `wc -c <'VMS/vms.c'`; then
- echo shar: \"'VMS/vms.c'\" unpacked with wrong size!
- fi
- # end of 'VMS/vms.c'
- fi
- if test -f 'unimplod.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'unimplod.c'\"
- else
- echo shar: Extracting \"'unimplod.c'\" \(9343 characters\)
- sed "s/^X//" >'unimplod.c' <<'END_OF_FILE'
- X/*---------------------------------------------------------------------------
- X
- X unimplod.c
- X
- X The Imploding algorithm is actually a combination of two distinct algor-
- X ithms. The first algorithm compresses repeated byte sequences using a
- X sliding dictionary. The second algorithm is used to compress the encoding
- X of the sliding dictionary ouput, using multiple Shannon-Fano trees.
- X
- X ---------------------------------------------------------------------------
- X
- X Copyrights: see accompanying file "COPYING" in UnZip source distribution.
- X
- X ---------------------------------------------------------------------------*/
- X
- X
- X#include "unzip.h"
- X
- X
- X/***********************/
- X/* UnImplode Defines */
- X/***********************/
- X
- X#define LITVALS 256
- X#define DISTVALS 64
- X#define LENVALS 64
- X#define MAXSF LITVALS
- X
- X
- X
- X/************************/
- X/* UnImplode Typedefs */
- X/************************/
- X
- Xtypedef struct sf_entry {
- X byte Value;
- X byte BitLength;
- X} sf_entry;
- X
- Xtypedef struct sf_tree { /* a shannon-fano "tree" (table) */
- X sf_entry entry[MAXSF];
- X int entries;
- X int MaxLength;
- X} sf_tree;
- X
- Xtypedef struct sf_node { /* node in a true shannon-fano tree */
- X UWORD left; /* 0 means leaf node */
- X UWORD right; /* or value if leaf node */
- X} sf_node;
- X
- X
- X
- X/********************************/
- X/* UnImplode Global Variables */
- X/********************************/
- X
- X/* s-f storage is shared with that used by other comp. methods */
- X
- Xsf_tree lit_tree;
- Xsf_tree length_tree;
- Xsf_tree distance_tree;
- Xsf_node *lit_nodes = (sf_node *) prefix_of; /* 2*LITVALS nodes */
- X#ifdef MACOS
- Xsf_node *length_nodes ; /* 2*LENVALS nodes */
- Xsf_node *distance_nodes ; /* 2*DISTVALS nodes */
- X#else
- Xsf_node *length_nodes = (sf_node *) suffix_of; /* 2*LENVALS nodes */
- Xsf_node *distance_nodes = (sf_node *) stack; /* 2*DISTVALS nodes */
- X#endif
- Xboolean lit_tree_present;
- Xboolean eightK_dictionary;
- Xint minimum_match_length;
- Xint dict_bits;
- X
- X
- X
- X/*****************************************/
- X/* UnImplode Local Function Prototypes */
- X/*****************************************/
- X
- Xstatic void LoadTrees __((void));
- Xstatic void LoadTree __((sf_tree * tree, int treesize, sf_node * nodes));
- Xstatic void ReadLengths __((sf_tree * tree));
- Xstatic void SortLengths __((sf_tree * tree));
- Xstatic void GenerateTrees __((sf_tree * tree, sf_node * nodes));
- Xstatic void ReadTree __((register sf_node * nodes, int *dest));
- X
- X
- X
- X
- X
- X/**************************/
- X/* Function unImplode() */
- X/**************************/
- X
- Xvoid unImplode()
- X /* expand imploded data */
- X{
- X register int srcix;
- X register int Length;
- X register int limit;
- X int lout;
- X int Distance;
- X
- X LoadTrees();
- X
- X#ifdef DEBUG
- X printf("\n");
- X#endif
- X while ((!zipeof) && ((outpos + outcnt) < ucsize)) {
- X READBIT(1, lout);
- X
- X if (lout != 0) { /* encoded data is literal data */
- X if (lit_tree_present) { /* use Literal Shannon-Fano tree */
- X ReadTree(lit_nodes, &lout);
- X#ifdef DEBUG
- X printf("lit=%d\n", lout);
- X#endif
- X } else
- X READBIT(8, lout);
- X
- X OUTB(lout);
- X } else { /* encoded data is sliding dictionary match */
- X READBIT(dict_bits, Distance);
- X
- X ReadTree(distance_nodes, &lout);
- X#ifdef DEBUG
- X printf("d=%5d (%2d,%3d)", (lout << dict_bits) | Distance, lout,
- X Distance);
- X#endif
- X Distance |= (lout << dict_bits);
- X /* using the Distance Shannon-Fano tree, read and decode the
- X upper 6 bits of the Distance value */
- X
- X ReadTree(length_nodes, &lout);
- X Length = lout;
- X#ifdef DEBUG
- X printf("\tl=%3d\n", Length);
- X#endif
- X /* using the Length Shannon-Fano tree, read and decode the
- X Length value */
- X
- X if (Length == 63) {
- X READBIT(8, lout);
- X Length += lout;
- X }
- X Length += minimum_match_length;
- X
- X /* move backwards Distance+1 bytes in the output stream, and copy
- X Length characters from this position to the output stream.
- X (if this position is before the start of the output stream,
- X then assume that all the data before the start of the output
- X stream is filled with zeros. Requires initializing outbuf
- X for each file.) */
- X
- X srcix = (outcnt - (Distance + 1)) & (OUTBUFSIZ - 1);
- X limit = OUTBUFSIZ - Length;
- X if ((srcix <= limit) && (outcnt < limit)) {
- X outcnt += Length;
- X while (Length--)
- X *outptr++ = outbuf[srcix++];
- X } else {
- X while (Length--) {
- X OUTB(outbuf[srcix++]);
- X srcix &= OUTBUFSIZ - 1;
- X }
- X }
- X }
- X }
- X}
- X
- X
- X
- X
- X
- X/**************************/
- X/* Function LoadTrees() */
- X/**************************/
- X
- Xstatic void LoadTrees()
- X{
- X eightK_dictionary = (lrec.general_purpose_bit_flag & 0x02) != 0; /* bit 1 */
- X lit_tree_present = (lrec.general_purpose_bit_flag & 0x04) != 0; /* bit 2 */
- X
- X if (eightK_dictionary)
- X dict_bits = 7;
- X else
- X dict_bits = 6;
- X
- X if (lit_tree_present) {
- X minimum_match_length = 3;
- X LoadTree(&lit_tree, 256, lit_nodes);
- X } else
- X minimum_match_length = 2;
- X
- X LoadTree(&length_tree, 64, length_nodes);
- X LoadTree(&distance_tree, 64, distance_nodes);
- X}
- X
- X
- X
- X
- X
- X/*************************/
- X/* Function LoadTree() */
- X/*************************/
- X
- Xstatic void LoadTree(tree, treesize, nodes)
- Xsf_tree *tree;
- Xint treesize;
- Xsf_node *nodes;
- X /* allocate and load a shannon-fano tree from the compressed file */
- X{
- X tree->entries = treesize;
- X ReadLengths(tree);
- X SortLengths(tree);
- X GenerateTrees(tree, nodes);
- X}
- X
- X
- X
- X
- X
- X/****************************/
- X/* Function ReadLengths() */
- X/****************************/
- X
- Xstatic void ReadLengths(tree)
- Xsf_tree *tree;
- X{
- X int treeBytes;
- X int i;
- X int num, len;
- X
- X /* get number of bytes in compressed tree */
- X READBIT(8, treeBytes);
- X treeBytes++;
- X i = 0;
- X
- X tree->MaxLength = 0;
- X
- X/* High 4 bits: Number of values at this bit length + 1. (1 - 16)
- X * Low 4 bits: Bit Length needed to represent value + 1. (1 - 16)
- X */
- X while (treeBytes > 0) {
- X READBIT(4, len);
- X len++;
- X READBIT(4, num);
- X num++;
- X
- X while (num > 0) {
- X if (len > tree->MaxLength)
- X tree->MaxLength = len;
- X tree->entry[i].BitLength = len;
- X tree->entry[i].Value = i;
- X i++;
- X num--;
- X }
- X
- X treeBytes--;
- X }
- X}
- X
- X
- X
- X
- X
- X/****************************/
- X/* Function SortLengths() */
- X/****************************/
- X
- Xstatic void SortLengths(tree)
- Xsf_tree *tree;
- X /* Sort the Bit Lengths in ascending order, while retaining the order
- X of the original lengths stored in the file */
- X{
- X register sf_entry *ejm1; /* entry[j - 1] */
- X register int j;
- X register sf_entry *entry;
- X register int i;
- X sf_entry tmp;
- X int entries;
- X unsigned a, b;
- X
- X entry = &tree->entry[0];
- X entries = tree->entries;
- X
- X for (i = 0; ++i < entries;) {
- X tmp = entry[i];
- X b = tmp.BitLength;
- X j = i;
- X while ((j > 0)
- X && ((a = (ejm1 = &entry[j - 1])->BitLength) >= b)) {
- X if ((a == b) && (ejm1->Value <= tmp.Value))
- X break;
- X *(ejm1 + 1) = *ejm1;/* entry[j] = entry[j - 1] */
- X --j;
- X }
- X entry[j] = tmp;
- X }
- X}
- X
- X
- X
- X
- X
- X/******************************/
- X/* Function GenerateTrees() */
- X/******************************/
- X
- Xstatic void GenerateTrees(tree, nodes)
- Xsf_tree *tree;
- Xsf_node *nodes;
- X /* Generate the Shannon-Fano trees */
- X{
- X int codelen, i, j, lvlstart, next, parents;
- X
- X i = tree->entries - 1; /* either 255 or 63 */
- X lvlstart = next = 1;
- X
- X /* believe it or not, there may be a 1-bit code */
- X
- X for (codelen = tree->MaxLength; codelen >= 1; --codelen) {
- X
- X /* create leaf nodes at level <codelen> */
- X
- X while ((i >= 0) && (tree->entry[i].BitLength == codelen)) {
- X nodes[next].left = 0;
- X nodes[next].right = tree->entry[i].Value;
- X ++next;
- X --i;
- X }
- X
- X /* create parent nodes for all nodes at level <codelen>,
- X but don't create the root node here */
- X
- X parents = next;
- X if (codelen > 1) {
- X for (j = lvlstart; j <= parents - 2; j += 2) {
- X nodes[next].left = j;
- X nodes[next].right = j + 1;
- X ++next;
- X }
- X }
- X lvlstart = parents;
- X }
- X
- X /* create root node */
- X
- X nodes[0].left = next - 2;
- X nodes[0].right = next - 1;
- X}
- X
- X
- X
- X
- X
- X/************************/
- X/* Function ReadTree() */
- X/************************/
- X
- X#ifndef ASM
- X
- Xstatic void ReadTree(nodes, dest)
- Xregister sf_node *nodes;
- Xint *dest;
- X /* read next byte using a shannon-fano tree */
- X{
- X register int cur;
- X register int left;
- X UWORD b;
- X
- X for (cur = 0;;) {
- X if ((left = nodes[cur].left) == 0) {
- X *dest = nodes[cur].right;
- X return;
- X }
- X READBIT(1, b);
- X cur = (b ? nodes[cur].right : left);
- X }
- X}
- X
- X#endif /* !ASM */
- END_OF_FILE
- if test 9343 -ne `wc -c <'unimplod.c'`; then
- echo shar: \"'unimplod.c'\" unpacked with wrong size!
- fi
- # end of 'unimplod.c'
- fi
- echo shar: End of archive 8 \(of 12\).
- cp /dev/null ark8isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 12 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-