home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume29 / unzip / part08 < prev    next >
Encoding:
Text File  |  1992-04-02  |  54.2 KB  |  1,803 lines

  1. Newsgroups: comp.sources.misc
  2. From: info-zip@cs.ucla.edu (Info-Zip)
  3. Subject:  v29i038:  unzip - Info-ZIP's portable UnZip v4.2, Part08/12
  4. Message-ID: <1992Apr3.063305.29044@sparky.imd.sterling.com>
  5. X-Md4-Signature: 66b1fd790fcb8bcabe1524123e87542d
  6. Date: Fri, 3 Apr 1992 06:33:05 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: info-zip@cs.ucla.edu (Info-Zip)
  10. Posting-number: Volume 29, Issue 38
  11. Archive-name: unzip/part08
  12. Environment: Unix, VMS, OS/2, MS-DOS, Amiga, Macintosh
  13. Supersedes: unzip, Volume 19, Issues 96-101
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  20. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  21. # Contents:  MSDOS/bcc/unzip_cr.prj.u VMS/VMSmunch.c VMS/vms.c
  22. #   unimplod.c
  23. # Wrapped by kent@sparky on Mon Mar 30 01:45:54 1992
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 8 (of 12)."'
  27. if test -f 'MSDOS/bcc/unzip_cr.prj.u' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'MSDOS/bcc/unzip_cr.prj.u'\"
  29. else
  30.   echo shar: Extracting \"'MSDOS/bcc/unzip_cr.prj.u'\" \(9233 characters\)
  31.   sed "s/^X//" >'MSDOS/bcc/unzip_cr.prj.u' <<'END_OF_FILE'
  32. Xbegin 666 MSDOS/bcc/unzip_cr.prj
  33. XM5'5R8F\@0R!0<F]J96-T($9I;&4@&@ !#1(7 1H  0<R $ 'R0 "  $ R@ "
  34. XM    RP "  $ S  "  $ S0 "  ( S@ "    SP "    T  "    T0 "    
  35. XMT@ "  $ TP "  $ U  "  , U@ " $  UP "  $ \0 !  #R  $  /,  0 !
  36. XM]  !  'U  $  ?8  @  @/<  0  ^  !  #Y  $  /H  @  (+ $ @   OL 
  37. XM 0  _  !  ']  $  /X  0  _P !     0$  0$! 0   P$!  $$ 0$   4!
  38. XM 0  !@$!  $' 0$ &0@! 0!D"0$! " * 0$   L! 0  # $!   - 0$   X!
  39. XM 0  #P$!   0 0$  !$! 0  $@$!   3 0$  !0! 0  %0$!  $6 0$  !<!
  40. XM @  @!@! 0  &0$"   !&@$!   ; 0$  !P! 0 !'0$!   > 0$  Q\! 0 !
  41. XM( $!   B 0$  ",! 0  ) $!   E 0$  "8! @#_?R<!   K 0(   !9 @$ 
  42. XM 6L" 0  6@(!  %; @$  5P" 0 !70(!  %> @$  5\" 0 !8 (!  %A @$ 
  43. XM 6(" 0 !8P(!  %D @$  64" 0 !9@(!  %G @$  6@" 0  :0(!  %L @$ 
  44. XM 6T" 0 !;@(!  %O @$  7 " 0 !<0(!  %R @$  7," 0 != (!  %U @$ 
  45. XM '8" 0 !=P(!  %X @$  7D" 0 !>@(!  %[ @$  7P" 0  C@(!  %] @$ 
  46. XM 7X" 0 !?P(!  &  @$  8$" 0 !@@(!  &# @$  80" 0 !A0(!  && @$ 
  47. XM 8<" 0 !B (!  &) @$  8H" 0 !BP(!  &, @$  8T" 0 !CP(!  &0 @$ 
  48. XM 9$" 0 !D@(!  &3 @$  2T!1                                   
  49. XM                                                         "X!
  50. XM@ !#.EQ"3U),04Y$7$E.0TQ51$4                                 
  51. XM                                                            
  52. XM                                                     "\!@ !#
  53. XM.EQ"3U),04Y$7$Q)0@                                          
  54. XM                                                            
  55. XM                                                 # !!  S,@  
  56. XM,0$% #(U    ,@$% #$P,   ,P%_ $-265!4 "!#4EE05               
  57. XM                                                            
  58. XM                                                            
  59. XM                   T 1X *@                                  
  60. XM    -0$> "H                                      #8!'@ J    
  61. XM                                   W 1X *@                  
  62. XM                    . $> "H                                 
  63. XM     #D!'@ J                                       Z 1X *@  
  64. XM                                    .P$> "H                 
  65. XM                     #P!'@ J                                
  66. XM       ] 1X *@                                      /@$> "H 
  67. XM                                     #\!'@ J                
  68. XM                      !  8                                  
  69. XM                                                            
  70. XM                                                            
  71. XM                  !$ 0@ ,S(W-C<   !% 0@ .#$Y,@    !& 7\     
  72. XM                                                            
  73. XM                                                            
  74. XM                                             $,!!0 N0P   /__
  75. XM   S  8  0"/8V<8"@#5" !^1U)%4                               
  76. XM                9W)E<                                       
  77. XM                                                            
  78. XM   M;BL@)$U%32@V-"D@)$Y/4U=!4" D4%)/35!4("1#05 @35-'*$=215 R
  79. XM35-'*79O:60@*BYC(                                           
  80. XM                                                            
  81. XM                                                            
  82. XM                             ,C_ 7Y4=7)B;R!!<W-E;6)L97(     
  83. XM                          !405--                            
  84. XM                                                            
  85. XM             "]-6" O6DD@+T\@)%1!4TT                         
  86. XM                                                            
  87. XM                                                            
  88. XM                                                            
  89. XM                                        R?\ 5'5R8F\@?D1E8G5G
  90. XM9V5R                                 '1D                    
  91. XM                                                            
  92. XM                        )$5814Y!344                         
  93. XM                                                            
  94. XM                                                            
  95. XM                                                            
  96. XM                                                  #*_P!4=7)B
  97. XM;R!^4')O9FEL97(                                 ='!R;V8     
  98. XM                                                            
  99. XM                                   D15A%3D%-10              
  100. XM                                                            
  101. XM                                                            
  102. XM                                                            
  103. XM                                                            
  104. XM ,O_ 5)^97-O=7)C92!#;VUP:6QE<@                            !2
  105. XM0P                                                          
  106. XM                                             "120P          
  107. XM                                                            
  108. XM                                                            
  109. XM                                                            
  110. XM                                                            
  111. XM            S/\!?DEM<&]R="!,:6)R87)I86X                     
  112. XM         $E-4$Q)0@                                          
  113. XM                                                        )$E-
  114. XM4$Q)0@                                                      
  115. XM                                                            
  116. XM                                                            
  117. XM                                                            
  118. XM                      #-____                                
  119. XM                                                            
  120. XM                                                            
  121. XM                                                            
  122. XM                                                            
  123. XM                                                            
  124. XM                                                            
  125. XM                                    -0 Z!   '@#28V<8$Q   -.3
  126. XM  "4!   54Y:25 N0P!53EI)4"Y#                                
  127. XM                                                       "  , 
  128. XM!  +       C5F<8__________\     1DE,15])3RY# $Q%7TE/+D,     
  129. XM                                                            
  130. XM                   %  8 !P *    (  H5F<89 (  )8    Y 0  34%0
  131. XM3D%-12Y# %!.04U%+D,                                         
  132. XM                                           +  P #0 )    %  L
  133. XM5F<82 (  !<   #+    34%40T@N0P!-051#2"Y#                    
  134. XM                                                            
  135. XM       .  \ $  (    %@ S5F<8P@0  $\$  "9 @  34E30RY# %Q-25-#
  136. XM+D,                                                         
  137. XM                               1 !( $P '    &  X5F<88 4  !@&
  138. XM  "  0  54Y)35!,3T0N0P!-4$Q/1"Y#                            
  139. XM                                                       4 !4 
  140. XM%@ &    &@ ]5F<8H ,  "(#  "^    54Y214150T4N0P!%1%5#12Y#    
  141. XM                                                            
  142. XM                   7 !@ &0 %    ' !$5F<8:@,   @   "S    54Y3
  143. XM2%))3DLN0P!(4DE.2RY#                                        
  144. XM                                           : !L '  $        
  145. XM    __________\     15A44D%#5"Y# %1204-4+D,                 
  146. XM                                                            
  147. XM       = !X 'P #            __________\     0U)94%0N0P!#4EE0
  148. XM5"Y#                                                        
  149. XM                               *  D "  "  " -@ >!2(   #__Q$%
  150. XM! 7D!,0$I 2$!& $/009!/P#W0.] YP#>P-: _____\Z DL#U@$^ W(!,@,.
  151. XM 2(#J@ 2 T8  @.> O__1@   !   P!YMF88!  EF&48!0  $! 7!@  $! 7
  152. XM!P  $! 7"   $! 7"0  $$T6"@  $! 7"P  $! 7#   $! 7#0  $! 7#@  
  153. XM$! 7#P  $! 7$   $! 7$0  $! 7__\    #   0 !\ <%R$%00 )9AE& 4 
  154. XM ! 0%P8  ! 0%P<  ! 0%P@  ! 0%PD  !!-%@H  ! 0%PL  ! 0%PP  ! 0
  155. XM%PT  ! 0%PX  ! 0%P\  ! 0%Q   ! 0%Q$  ! 0%___3" @(   $  = /:B
  156. XM8A<$ "6891@%   0$!<&   0$!<'   0$!<(   0$!<)   0318*   0$!<+
  157. XM   0$!<,   0$!<-   0$!<.   0$!</   0$!<0   0$!<1   0$!?__TP@
  158. XM("   !  &P"EA4$8!  EF&48!0  $! 7!@  $! 7!P  $! 7"   $! 7"0  
  159. XM$$T6"@  $! 7"P  $! 7#   $! 7#0  $! 7#@  $! 7#P  $! 7$   $! 7
  160. XM$0  $! 7__],(" @   0 !D 3(YC& 0 )9AE& 4  ! 0%P8  ! 0%P<  ! 0
  161. XM%P@  ! 0%PD  !!-%@H  ! 0%PL  ! 0%PP  ! 0%PT  ! 0%PX  ! 0%P\ 
  162. XM ! 0%Q   ! 0%Q$  ! 0%___3" @(   $  7 &R.01@$ "6891@%   0$!<&
  163. XM   0$!<'   0$!<(   0$!<)   0318*   0$!<+   0$!<,   0$!<-   0
  164. XM$!<.   0$!</   0$!<0   0$!<1   0$!?__TP@("   !  %0#0?&48!  E
  165. XMF&48!0  $! 7!@  $! 7!P  $! 7"   $! 7"0  $$T6"@  $! 7"P  $! 7
  166. XM#   $! 7#0  $! 7#@  $! 7#P  $! 7$   $! 7$0  $! 7__],(" @____
  167. XM__]53E-(4DE.2RY# /______54Y214150T4N0P#______U5.24U03$]$+D, 
  168. XM______]-25-#+D, ______]-051#2"Y# /______34%03D%-12Y# /______
  169. XM+BY<0D]23$%.1%Q)3D-,541%7$Q)34E44RY( /______+BY<0D]23$%.1%Q)
  170. XM3D-,541%7%-44DE.1RY( /______+BY<0D]23$%.1%Q)3D-,541%7%-41$Q)
  171. XM0BY( /______+BY<0D]23$%.1%Q)3D-,541%7$9#3E1,+D@ ______\N+EQ"
  172. XM3U),04Y$7$E.0TQ51$5<5$E-12Y( /______+BY<0D]23$%.1%Q)3D-,541%
  173. XM7$E/+D@ ______\N+EQ"3U),04Y$7$E.0TQ51$5<4UE37%1)345"+D@ ____
  174. XM__\N+EQ"3U),04Y$7$E.0TQ51$5<4UE37%-4050N2 #______RXN7$)/4DQ!
  175. XM3D1<24Y#3%5$15Q365-<5%E015,N2 #______RXN7$)/4DQ!3D1<24Y#3%5$
  176. XM15Q%4E).3RY( /______+BY<0D]23$%.1%Q)3D-,541%7$-465!%+D@ ____
  177. XM__\N+EQ"3U),04Y$7$E.0TQ51$5<7T1%1E,N2 #______RXN7$)/4DQ!3D1<
  178. XM24Y#3%5$15Q35$1)3RY( /______54Y:25 N2 #______U5.6DE0+D, -P!@
  179. XM "    !? %X 70!< %L 6@!" $, 1 !9 %@ 5P!6 %4 5 !3 %( 40!0 $\ 
  180. XM3@!- $P 2P!* $D 2 !' $8 10!"                                
  181. X+         /__    
  182. Xend
  183. END_OF_FILE
  184.   if test 9233 -ne `wc -c <'MSDOS/bcc/unzip_cr.prj.u'`; then
  185.     echo shar: \"'MSDOS/bcc/unzip_cr.prj.u'\" unpacked with wrong size!
  186.   else
  187.     echo shar: Uudecoding \"'MSDOS/bcc/unzip_cr.prj.u'\"
  188.     cat MSDOS/bcc/unzip_cr.prj.u | uudecode
  189.     if [ -f MSDOS/bcc/unzip_cr.prj.u ]; then
  190.        rm MSDOS/bcc/unzip_cr.prj.u
  191.     fi
  192.   fi
  193.   # end of 'MSDOS/bcc/unzip_cr.prj.u'
  194. fi
  195. if test -f 'VMS/VMSmunch.c' -a "${1}" != "-c" ; then 
  196.   echo shar: Will not clobber existing file \"'VMS/VMSmunch.c'\"
  197. else
  198.   echo shar: Extracting \"'VMS/VMSmunch.c'\" \(11678 characters\)
  199.   sed "s/^X//" >'VMS/VMSmunch.c' <<'END_OF_FILE'
  200. X/*---------------------------------------------------------------------------
  201. X
  202. X  VMSmunch.c                    version 1.1                      7 Feb 1992
  203. X
  204. X  This routine is a blatant and unrepentent appropriation of all the nasty
  205. X  and difficult-to-do and complicated VMS shenanigans which Joe Meadows has
  206. X  so magnificently captured in his FILE utility.  Not only that, it's even
  207. X  allowed! (see below).  But let it be clear at the outset that Joe did all
  208. X  the work; yea, verily, he is truly a godlike unit.
  209. X
  210. X  The appropriations and modifications herein were performed primarily by
  211. X  him known as "Cave Newt," although the Info-ZIP working group probably had
  212. X  their fingers in it somewhere along the line.  The idea is to put the raw
  213. X  power of Joe's original routine at the disposal of various routines used
  214. X  by UnZip (and Zip, possibly), not least among them the utime() function.
  215. X  Read on for details...
  216. X
  217. X  ---------------------------------------------------------------------------
  218. X
  219. X  Usage (i.e., "interface," in geek-speak):
  220. X
  221. X     int VMSmunch( char *filename, int action, char *ptr );
  222. X
  223. X     filename   the name of the file on which to be operated, obviously
  224. X     action     an integer which specifies what action to take
  225. X     ptr        pointer to any extra item which may be needed (else NULL)
  226. X
  227. X  The possible values for the action argument are as follows:
  228. X
  229. X     GET_TIMES      get the creation and revision dates of filename; ptr
  230. X                    must point to an empty VMStimbuf struct, as defined below
  231. X                    (with room for at least 24 characters, including term.)
  232. X     SET_TIMES      set the creation and revision dates of filename (utime
  233. X                    option); ptr must point to a valid VMStimbuf struct,
  234. X                    as defined below
  235. X     GET_RTYPE      get the record type of filename; ptr must point to an
  236. X                    integer which, on return, is set to the type (as defined
  237. X                    in fatdef.h:  FAT$C_* defines)
  238. X     CHANGE_RTYPE   change the record type to that specified by the integer
  239. X                    to which ptr points; save the old record type (later
  240. X                    saves overwrite earlier ones)
  241. X     RESTORE_RTYPE  restore the record type to the previously saved value;
  242. X                    or, if none, set it to "fixed-length, 512-byte" record
  243. X                    format (ptr not used)
  244. X
  245. X  ---------------------------------------------------------------------------
  246. X
  247. X  Comments from FILE.C, a utility to modify file characteristics:
  248. X
  249. X     Written by Joe Meadows Jr, at the Fred Hutchinson Cancer Research Center
  250. X     BITNET: JOE@FHCRCVAX
  251. X     PHONE: (206) 467-4970
  252. X
  253. X     There are no restrictions on this code, you may sell it, include it 
  254. X     with any commercial package, or feed it to a whale.. However, I would 
  255. X     appreciate it if you kept this comment in the source code so that anyone
  256. X     receiving this code knows who to contact in case of problems. Note that 
  257. X     I do not demand this condition..
  258. X
  259. X  ---------------------------------------------------------------------------*/
  260. X
  261. X
  262. X
  263. X
  264. X/*****************************/
  265. X/*  Includes, Defines, etc.  */
  266. X/*****************************/
  267. X
  268. X#include <descrip.h>
  269. X#include <rms.h>
  270. X#include <stdio.h>
  271. X#include <iodef.h>
  272. X#include <atrdef.h>   /* this gets created with the c3.0 compiler */
  273. X#include <fibdef.h>   /* this gets created with the c3.0 compiler */
  274. X
  275. X#include "fatdef.h"
  276. X#include "fchdef.h"
  277. X#include "fjndef.h"
  278. X
  279. X#include "VMSmunch.h"  /* GET/SET_TIMES, RTYPE, etc. */
  280. X
  281. X#define RTYPE     fat$r_rtype_overlay.fat$r_rtype_bits
  282. X#define RATTRIB   fat$r_rattrib_overlay.fat$r_rattrib_bits
  283. X
  284. Xstatic void asctim();
  285. Xstatic void bintim();
  286. X
  287. Xstruct VMStimbuf {      /* VMSmunch */
  288. X    char *actime;       /* VMS revision date, ASCII format */
  289. X    char *modtime;      /* VMS creation date, ASCII format */
  290. X};
  291. X
  292. X/* from <ssdef.h> */
  293. X#ifndef SS$_NORMAL
  294. X#  define SS$_NORMAL    1
  295. X#  define SS$_BADPARAM  20
  296. X#endif
  297. X
  298. X
  299. X
  300. X
  301. X
  302. X/*************************/
  303. X/*  Function VMSmunch()  */
  304. X/*************************/
  305. X
  306. Xint VMSmunch( filename, action, ptr )
  307. X    char  *filename, *ptr;
  308. X    int   action;
  309. X{
  310. X
  311. X    /* original file.c variables */
  312. X
  313. X    static struct FAB Fab;
  314. X    static struct NAM Nam;
  315. X    static struct fibdef Fib; /* short fib */
  316. X
  317. X    static struct dsc$descriptor FibDesc =
  318. X      {sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,&Fib};
  319. X    static struct dsc$descriptor_s DevDesc =
  320. X      {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.nam$t_dvi[1]};
  321. X    static struct fatdef Fat;
  322. X    static union {
  323. X      struct fchdef fch;
  324. X      long int dummy;
  325. X    } uchar;
  326. X    static struct fjndef jnl;
  327. X    static long int Cdate[2],Rdate[2],Edate[2],Bdate[2];
  328. X    static short int revisions;
  329. X    static unsigned long uic;
  330. X    static union {
  331. X      unsigned short int value;
  332. X      struct {
  333. X        unsigned system : 4;
  334. X        unsigned owner : 4;
  335. X        unsigned group : 4;
  336. X        unsigned world : 4;
  337. X      } bits;
  338. X    } prot;
  339. X
  340. X    static struct atrdef Atr[] = {
  341. X      {sizeof(Fat),ATR$C_RECATTR,&Fat},        /* record attributes */
  342. X      {sizeof(uchar),ATR$C_UCHAR,&uchar},      /* File characteristics */
  343. X      {sizeof(Cdate),ATR$C_CREDATE,&Cdate[0]}, /* Creation date */
  344. X      {sizeof(Rdate),ATR$C_REVDATE,&Rdate[0]}, /* Revision date */
  345. X      {sizeof(Edate),ATR$C_EXPDATE,&Edate[0]}, /* Expiration date */
  346. X      {sizeof(Bdate),ATR$C_BAKDATE,&Bdate[0]}, /* Backup date */
  347. X      {sizeof(revisions),ATR$C_ASCDATES,&revisions}, /* number of revisions */
  348. X      {sizeof(prot),ATR$C_FPRO,&prot},         /* file protection  */
  349. X      {sizeof(uic),ATR$C_UIC,&uic},            /* file owner */
  350. X      {sizeof(jnl),ATR$C_JOURNAL,&jnl},        /* journal flags */
  351. X      {0,0,0}
  352. X    } ;
  353. X
  354. X    static char EName[NAM$C_MAXRSS];
  355. X    static char RName[NAM$C_MAXRSS];
  356. X    static struct dsc$descriptor_s FileName =
  357. X      {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  358. X    static struct dsc$descriptor_s string = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  359. X    static short int DevChan;
  360. X    static short int iosb[4];
  361. X
  362. X    static long int i,status;
  363. X/*  static char *retval;  */
  364. X
  365. X
  366. X    /* new VMSmunch variables */
  367. X
  368. X    static int  old_rtype=FAT$C_FIXED;   /* storage for record type */
  369. X
  370. X
  371. X
  372. X/*---------------------------------------------------------------------------
  373. X    Initialize attribute blocks, parse filename, resolve any wildcards, and
  374. X    get the file info.
  375. X  ---------------------------------------------------------------------------*/
  376. X
  377. X    /* initialize RMS structures, we need a NAM to retrieve the FID */
  378. X    Fab = cc$rms_fab;
  379. X    Fab.fab$l_fna = filename;
  380. X    Fab.fab$b_fns = strlen(filename);
  381. X    Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */
  382. X    Nam = cc$rms_nam;
  383. X    Nam.nam$l_esa = &EName; /* expanded filename */
  384. X    Nam.nam$b_ess = sizeof(EName);
  385. X    Nam.nam$l_rsa = &RName; /* resultant filename */
  386. X    Nam.nam$b_rss = sizeof(RName);
  387. X
  388. X    /* do $PARSE and $SEARCH here */
  389. X    status = sys$parse(&Fab);
  390. X    if (!(status & 1)) return(status);
  391. X
  392. X    /* search for the first file.. If none signal error */
  393. X    status = sys$search(&Fab);
  394. X    if (!(status & 1)) return(status);
  395. X
  396. X    while (status & 1) {
  397. X        /* initialize Device name length, note that this points into the NAM
  398. X           to get the device name filled in by the $PARSE, $SEARCH services */
  399. X        DevDesc.dsc$w_length = Nam.nam$t_dvi[0];
  400. X
  401. X        status = sys$assign(&DevDesc,&DevChan,0,0);
  402. X        if (!(status & 1)) return(status);
  403. X
  404. X        FileName.dsc$a_pointer = Nam.nam$l_name;
  405. X        FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver;
  406. X
  407. X        /* Initialize the FIB */
  408. X        for (i=0;i<3;i++)
  409. X            Fib.fib$r_fid_overlay.fib$w_fid[i]=Nam.nam$w_fid[i];
  410. X        for (i=0;i<3;i++)
  411. X            Fib.fib$r_did_overlay.fib$w_did[i]=Nam.nam$w_did[i];
  412. X
  413. X        /* Use the IO$_ACCESS function to return info about the file */
  414. X        /* Note, used this way, the file is not opened, and the expiration */
  415. X        /* and revision dates are not modified */
  416. X        status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0,
  417. X                          &FibDesc,&FileName,0,0,&Atr,0);
  418. X        if (!(status & 1)) return(status);
  419. X        status = iosb[0];
  420. X        if (!(status & 1)) return(status);
  421. X
  422. X    /*-----------------------------------------------------------------------
  423. X        We have the current information from the file:  now see what user
  424. X        wants done with it.
  425. X      -----------------------------------------------------------------------*/
  426. X
  427. X        switch (action) {
  428. X
  429. X          case GET_TIMES:
  430. X              asctim(((struct VMStimbuf *)ptr)->modtime, Cdate);
  431. X              asctim(((struct VMStimbuf *)ptr)->actime, Rdate);
  432. X              break;
  433. X
  434. X          case SET_TIMES:
  435. X              bintim(((struct VMStimbuf *)ptr)->modtime, Cdate);
  436. X              bintim(((struct VMStimbuf *)ptr)->actime, Rdate);
  437. X              break;
  438. X
  439. X          case GET_RTYPE:   /* non-modifying */
  440. X              *(int *)ptr = Fat.RTYPE.fat$v_rtype;
  441. X              return RMS$_NORMAL;     /* return to user */
  442. X              break;
  443. X
  444. X          case CHANGE_RTYPE:
  445. X              old_rtype = Fat.RTYPE.fat$v_rtype;         /* save current one */
  446. X              if ((*(int *)ptr < FAT$C_UNDEFINED) || 
  447. X                  (*(int *)ptr > FAT$C_STREAMCR))
  448. X                  Fat.RTYPE.fat$v_rtype = FAT$C_STREAMLF;  /* Unix I/O happy */
  449. X              else
  450. X                  Fat.RTYPE.fat$v_rtype = *(int *)ptr;
  451. X              break;
  452. X
  453. X          case RESTORE_RTYPE:
  454. X              Fat.RTYPE.fat$v_rtype = old_rtype;
  455. X              break;
  456. X
  457. X          default:
  458. X              return SS$_BADPARAM;   /* anything better? */
  459. X        }
  460. X
  461. X    /*-----------------------------------------------------------------------
  462. X        Go back and write modified data to the file header.
  463. X      -----------------------------------------------------------------------*/
  464. X
  465. X        /* note, part of the FIB was cleared by earlier QIOW, so reset it */
  466. X        Fib.fib$r_acctl_overlay.fib$l_acctl = FIB$M_NORECORD;
  467. X        for (i=0;i<3;i++)
  468. X            Fib.fib$r_fid_overlay.fib$w_fid[i]=Nam.nam$w_fid[i];
  469. X        for (i=0;i<3;i++)
  470. X            Fib.fib$r_did_overlay.fib$w_did[i]=Nam.nam$w_did[i];
  471. X
  472. X        /* Use the IO$_MODIFY function to change info about the file */
  473. X        /* Note, used this way, the file is not opened, however this would */
  474. X        /* normally cause the expiration and revision dates to be modified. */
  475. X        /* Using FIB$M_NORECORD prohibits this from happening. */
  476. X        status = sys$qiow(0,DevChan,IO$_MODIFY,&iosb,0,0,
  477. X                          &FibDesc,&FileName,0,0,&Atr,0);
  478. X        if (!(status & 1)) return(status);
  479. X
  480. X        status = iosb[0];
  481. X        if (!(status & 1)) return(status);
  482. X
  483. X        status = sys$dassgn(DevChan);
  484. X        if (!(status & 1)) return(status);
  485. X
  486. X        /* look for next file, if none, no big deal.. */
  487. X        status = sys$search(&Fab);
  488. X    }
  489. X} /* end function VMSmunch() */
  490. X
  491. X
  492. X
  493. X
  494. X
  495. X/***********************/
  496. X/*  Function bintim()  */
  497. X/***********************/
  498. X
  499. Xvoid asctim(time,binval)   /* convert 64-bit binval to string, put in time */
  500. X    char *time;
  501. X    long int binval[2];
  502. X{
  503. X    static struct dsc$descriptor date_str={23,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  504. X      /* dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer */
  505. X    date_str.dsc$a_pointer = time;
  506. X    sys$asctim(0, &date_str, binval, 0);
  507. X    time[23] = '\0';
  508. X}
  509. X
  510. X
  511. X
  512. X
  513. X
  514. X/***********************/
  515. X/*  Function bintim()  */
  516. X/***********************/
  517. X
  518. Xvoid bintim(time,binval)   /* convert time string to 64 bits, put in binval */
  519. X    char *time;
  520. X    long int binval[2];
  521. X{
  522. X    static struct dsc$descriptor date_str={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  523. X
  524. X    date_str.dsc$w_length = strlen(time);
  525. X    date_str.dsc$a_pointer = time;
  526. X    sys$bintim(&date_str, binval);
  527. X}
  528. END_OF_FILE
  529.   if test 11678 -ne `wc -c <'VMS/VMSmunch.c'`; then
  530.     echo shar: \"'VMS/VMSmunch.c'\" unpacked with wrong size!
  531.   fi
  532.   # end of 'VMS/VMSmunch.c'
  533. fi
  534. if test -f 'VMS/vms.c' -a "${1}" != "-c" ; then 
  535.   echo shar: Will not clobber existing file \"'VMS/vms.c'\"
  536. else
  537.   echo shar: Extracting \"'VMS/vms.c'\" \(20178 characters\)
  538.   sed "s/^X//" >'VMS/vms.c' <<'END_OF_FILE'
  539. X/*************************************************************************
  540. X *                                                                       *
  541. X * Copyright (C) 1992 Igor Mandrichenko.                                 *
  542. X * Permission is granted to any individual or institution to use, copy,  *
  543. X * or redistribute this software so long as all of the original files    *
  544. X * are included unmodified, that it is not sold for profit, and that     *
  545. X * this copyright notice is retained.                                    *
  546. X *                                                                       *
  547. X *************************************************************************/
  548. X
  549. X/*
  550. X *    vms.c  by Igor Mandrichenko
  551. X *    version 1.1-2
  552. X *
  553. X *    This module contains routines to extract VMS file attributes
  554. X *    from extra field and create file with these attributes.  This
  555. X *    source is mainly based on sources of file_io.c from UNZIP 4.1
  556. X *    by Info-ZIP.  [Info-ZIP note:  very little of this code is from
  557. X *    file_io.c; it has virtually been written from the ground up.
  558. X *    Of the few lines which are from the older code, most are mine
  559. X *    (G. Roelofs) and I make no claims upon them.  On the contrary,
  560. X *    my/our thanks to Igor for his contributions!]
  561. X */
  562. X
  563. X/* 
  564. X *    Revision history:
  565. X *    1.0-1    Mandrichenko    16-feb-1992
  566. X *        Recognize -c option
  567. X *    1.0-2    Mandrichenko    17-feb-1992
  568. X *        Do not use ASYnchroneous mode.
  569. X *    1.0-3   Mandrichenko    2-mar-1992
  570. X *        Make code more standard
  571. X *        Use lrec instead of crec -- unzip4.2p do not provide 
  572. X *        crec now.
  573. X *      1.1    Mandrichenko    5-mar-1992  
  574. X *        Make use of asynchronous output.
  575. X *        Be ready to extract RMS blocks of invalid size (because diff
  576. X *              VMS version used to compress).
  577. X *    1.1-1    Mandrichenko    11-mar-1992
  578. X *        Use internal file attributes saved in pInfo to decide
  579. X *        if the file is text.  [GRR:  temporarily disabled, since
  580. X *              no way to override and force binary extraction]
  581. X *    1.1-2   Mandrichenko    13-mar-1992
  582. X *        Do not restore owner/protection info if -X not specified.
  583. X */
  584. X
  585. X#ifdef VMS            /*    VMS only !    */
  586. X
  587. X/************************************/
  588. X/*  File_IO Includes, Defines, etc. */
  589. X/************************************/
  590. X
  591. X#ifdef VAXC
  592. X#include rms
  593. X#include descrip
  594. X#include syidef
  595. X#else
  596. X#include <rms.h>
  597. X#include <descrip.h>
  598. X#include <syidef.h>
  599. X#endif
  600. X
  601. X#include "unzip.h"
  602. X
  603. X#define ERR(s) !((s) & 1)
  604. X
  605. X#define BUFS512    8192*2    /* Must be a multiple of 512 */
  606. X
  607. Xstatic int WriteBuffer __((int fd, unsigned char *buf, int len));
  608. Xstatic int _flush_blocks __((void));
  609. Xstatic int _flush_records __((void));
  610. Xstatic byte *extract_block __((byte *));
  611. X
  612. X/*
  613. X*   Local static storage
  614. X*/
  615. Xstatic struct FAB *outfab = 0;
  616. Xstatic struct RAB *outrab = 0;
  617. Xstatic struct FAB fileblk;
  618. Xstatic struct XABFHC *xabfhc = 0;
  619. Xstatic struct XABDAT dattim, *xabdat = 0;
  620. Xstatic struct XABRDT *xabrdt = 0;
  621. Xstatic struct XABPRO *xabpro = 0;
  622. Xstatic struct XABKEY *xabkey = 0;
  623. Xstatic struct XABALL *xaball = 0;
  624. Xstatic struct RAB rab;
  625. X
  626. Xstatic int text_file = 0;
  627. X
  628. Xstatic char locbuf[BUFS512];
  629. Xstatic int loccnt = 0;
  630. Xstatic char *locptr;
  631. X
  632. X
  633. Xstruct bufdsc
  634. X{    struct bufdsc    *next;
  635. X    byte *buf;
  636. X    int bufcnt;
  637. X};
  638. X
  639. Xstatic struct bufdsc b1,b2,*curbuf;
  640. Xstatic byte buf1[BUFS512],buf2[BUFS512];
  641. X
  642. Xint create_output_file()
  643. X{                /* return non-0 if sys$create failed */
  644. X    int ierr, yr, mo, dy, hh, mm, ss;
  645. X    char timbuf[24];        /* length = first entry in "stupid" + 1 */
  646. X    int attr_given = 0;        /* =1 if VMS attributes are present in
  647. X                *     extra_field */
  648. X
  649. X    rab = cc$rms_rab;        /* fill FAB & RAB with default values */
  650. X    fileblk = cc$rms_fab;
  651. X
  652. X    text_file = /* pInfo->text || */ aflag || cflag;
  653. X
  654. X    if (attr_given = find_vms_attrs())
  655. X    {    text_file = 0;
  656. X    if( cflag )
  657. X    {    printf("Can not put VMS file %s to stdout.\n",
  658. X            filename);
  659. X        return 50;
  660. X    }
  661. X    }
  662. X    
  663. X    if (!attr_given)
  664. X    {
  665. X    outfab = &fileblk;
  666. X    outfab->fab$l_xab = 0L;
  667. X    if (text_file)
  668. X    {
  669. X        outfab->fab$b_rfm = FAB$C_VAR;    /* variable length records */
  670. X        outfab->fab$b_rat = FAB$M_CR;    /* carriage-return carriage ctrl */
  671. X    }
  672. X    else
  673. X    {
  674. X        outfab->fab$b_rfm = FAB$C_STMLF;    /* stream-LF record format */
  675. X        outfab->fab$b_rat = FAB$M_CR;    /* carriage-return carriage ctrl */
  676. X    }
  677. X    }
  678. X
  679. X    if(!cflag)
  680. X        outfab->fab$l_fna = filename;
  681. X    else
  682. X        outfab->fab$l_fna = "sys$output:";
  683. X
  684. X    outfab->fab$b_fns = strlen(outfab->fab$l_fna);
  685. X
  686. X    if (!attr_given || xabdat == 0)
  687. X    {
  688. X    static char *month[] =
  689. X        {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
  690. X         "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
  691. X    /*  fixed-length string descriptor (why not just a pointer to timbuf? sigh.) */
  692. X    struct dsc$descriptor stupid =
  693. X        {23, DSC$K_DTYPE_T, DSC$K_CLASS_S, timbuf};
  694. X
  695. X    yr = ((lrec.last_mod_file_date >> 9) & 0x7f) + 1980;    /* dissect date */
  696. X    mo = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1;
  697. X    dy = (lrec.last_mod_file_date & 0x1f);
  698. X    hh = (lrec.last_mod_file_time >> 11) & 0x1f;    /* dissect time */
  699. X    mm = (lrec.last_mod_file_time >> 5) & 0x3f;
  700. X    ss = (lrec.last_mod_file_time & 0x1f) * 2;
  701. X
  702. X    dattim = cc$rms_xabdat;    /* fill XAB with default values */
  703. X    dattim.xab$l_nxt = outfab->fab$l_xab;
  704. X    outfab->fab$l_xab = (char*)(xabdat = &dattim);
  705. X
  706. X    sprintf(timbuf, "%02d-%3s-%04d %02d:%02d:%02d.00", dy, month[mo], yr,
  707. X        hh, mm, ss);
  708. X    sys$bintim(&stupid, &dattim.xab$q_cdt);
  709. X    }
  710. X
  711. X#ifdef DEBUG
  712. X    printf("XAB chain before CREATE dump:\n");
  713. X    dump_rms_block(outfab);
  714. X    {
  715. X    struct XABALL *x;
  716. X    for (x = outfab->fab$l_xab; x != 0L; x = x->xab$l_nxt)
  717. X        dump_rms_block(x);
  718. X    }
  719. X#endif
  720. X
  721. X    outfab->fab$w_ifi = 0;    /* Clear IFI. It may be nonzero after ZIP */
  722. X
  723. X    if ((ierr = sys$create(outfab)) != RMS$_NORMAL)
  724. X    {
  725. X    message("[ can not create output file ]\n", ierr);
  726. X    message("", outfab->fab$l_stv);
  727. X    fprintf(stderr, "Can't create output file:  %s\n", filename);
  728. X    return (1);
  729. X    }
  730. X
  731. X    if (!text_file && !cflag)    /* Do not reopen text files and stdout
  732. X                *  Just open them in right mode        */
  733. X    {
  734. X    /*
  735. X    *    Reopen file for Block I/O with no XABs.
  736. X    */
  737. X    if ((ierr = sys$close(outfab)) != RMS$_NORMAL)
  738. X    {
  739. X#ifdef DEBUG
  740. X        message("[ create_output_file: sys$close failed ]\n", ierr);
  741. X        message("", outfab->fab$l_stv);
  742. X#endif
  743. X        fprintf(stderr, "Can't create output file:  %s\n", filename);
  744. X        return (1);
  745. X    }
  746. X
  747. X
  748. X    outfab->fab$b_fac = FAB$M_BIO | FAB$M_PUT;    /* Get ready for block
  749. X                             * output */
  750. X    outfab->fab$l_xab = 0L;    /* Unlink all XABs */
  751. X
  752. X    if ((ierr = sys$open(outfab)) != RMS$_NORMAL)
  753. X    {
  754. X        message("[ Can not open output file ]\n", ierr);
  755. X        message("", outfab->fab$l_stv);
  756. X        return (1);
  757. X    }
  758. X    }
  759. X
  760. X    outrab = &rab;
  761. X    rab.rab$l_fab = outfab;
  762. X    if( !text_file ) rab.rab$l_rop |= RAB$M_BIO;
  763. X    if( !text_file ) rab.rab$l_rop |= RAB$M_ASY;
  764. X    rab.rab$b_rac = RAB$C_SEQ;
  765. X
  766. X    if ((ierr = sys$connect(outrab)) != RMS$_NORMAL)
  767. X    {
  768. X#ifdef DEBUG
  769. X    fprintf(stderr, "create_output_file: sys$connect failed on file %s\n",
  770. X        filename);
  771. X    fprintf(stderr, "                    status = %d\n", ierr);
  772. X    fprintf(stderr, "                   fab.sts = %d\n", outfab->fab$l_sts);
  773. X    fprintf(stderr, "                   fab.stv = %d\n", outfab->fab$l_stv);
  774. X#endif
  775. X    fprintf(stderr, "Can't create output file:  %s\n", filename);
  776. X    return (1);
  777. X    }
  778. X
  779. X    locptr = &locbuf[0];
  780. X    loccnt = 0;
  781. X
  782. X    b1.buf = &buf1[0];
  783. X    b1.bufcnt = 0;
  784. X    b1.next = &b2;
  785. X    b2.buf = &buf2[0];
  786. X    b2.bufcnt = 0;
  787. X    b2.next = &b1;
  788. X    curbuf = &b1;
  789. X
  790. X    return (0);
  791. X}
  792. X
  793. X/*
  794. X*   Extra record format
  795. X*   ===================
  796. X*   signature         (2 bytes)    = 'I','M'
  797. X*   size        (2 bytes)
  798. X*   block signature (4 bytes)
  799. X*   flags        (2 bytes)
  800. X*   uncomprssed size(2 bytes) 
  801. X*   reserved        (4 bytes) 
  802. X*   data        ((size-12) bytes)
  803. X*   ....
  804. X*/
  805. X
  806. Xstruct extra_block
  807. X{
  808. X    UWORD sig;            /* Extra field block header structure */
  809. X    UWORD size;
  810. X    ULONG bid;
  811. X    UWORD flags;
  812. X    UWORD length;
  813. X    ULONG reserved;
  814. X    byte body[1];
  815. X};
  816. X
  817. X/*
  818. X *   Extra field signature and block signatures
  819. X */
  820. X
  821. X#define SIGNATURE "IM"
  822. X#define FABL    (cc$rms_fab.fab$b_bln)
  823. X#define RABL    (cc$rms_rab.rab$b_bln)
  824. X#define XALLL    (cc$rms_xaball.xab$b_bln)
  825. X#define XDATL    (cc$rms_xabdat.xab$b_bln)
  826. X#define XFHCL    (cc$rms_xabfhc.xab$b_bln)
  827. X#define XKEYL    (cc$rms_xabkey.xab$b_bln)
  828. X#define XPROL    (cc$rms_xabpro.xab$b_bln)
  829. X#define XRDTL    (cc$rms_xabrdt.xab$b_bln)
  830. X#define XSUML    (cc$rms_xabsum.xab$b_bln)
  831. X#define EXTBSL  4        /* Block signature length   */
  832. X#define RESL    8        /* Rserved 8 bytes  */
  833. X#define EXTHL    (4+EXTBSL)
  834. X#define FABSIG    "VFAB"
  835. X#define XALLSIG    "VALL"
  836. X#define XFHCSIG    "VFHC"
  837. X#define XDATSIG    "VDAT"
  838. X#define XRDTSIG    "VRDT"
  839. X#define XPROSIG    "VPRO"
  840. X#define XKEYSIG    "VKEY"
  841. X#define XNAMSIG    "VNAM"
  842. X#define VERSIG  "VMSV"
  843. X
  844. X
  845. X
  846. X#define W(p)    (*(unsigned short*)(p))
  847. X#define L(p)    (*(unsigned long*)(p))
  848. X#define EQL_L(a,b)    ( L(a) == L(b) )
  849. X#define EQL_W(a,b)    ( W(a) == W(b) )
  850. X
  851. X/****************************************************************
  852. X * Function find_vms_attrs scans ZIP entry extra field if any   *
  853. X * and looks for VMS attribute records. Returns 0 if either no  *
  854. X * attributes found or no fab given.                            *
  855. X ****************************************************************/
  856. Xint find_vms_attrs()
  857. X{
  858. X    byte *scan = extra_field;
  859. X    struct extra_block *blk;
  860. X    struct XABALL *first_xab = 0L, *last_xab = 0L;
  861. X    int len;
  862. X
  863. X    outfab = xabfhc = xabdat = xabrdt = xabpro = 0L;
  864. X
  865. X    if (scan == NULL)
  866. X    return 0;
  867. X/*
  868. X    if (crec.extra_field_length)
  869. X    len = crec.extra_field_length;
  870. X    else
  871. X*/
  872. X    len = lrec.extra_field_length;
  873. X
  874. X#define LINK(p)    {                     \
  875. X        if( first_xab == 0L )            \
  876. X            first_xab = p;            \
  877. X        if( last_xab != 0L )            \
  878. X            last_xab -> xab$l_nxt = p;    \
  879. X        last_xab = p;                \
  880. X        p -> xab$l_nxt = 0;            \
  881. X    }
  882. X    /* End of macro LINK */
  883. X
  884. X    while (len > 0)
  885. X    {
  886. X    blk = (struct block *)scan;
  887. X    if (EQL_W(&blk->sig, SIGNATURE))
  888. X    {
  889. X        byte *block_id;
  890. X        block_id = &blk->bid;
  891. X        if (EQL_L(block_id, FABSIG))
  892. X        {
  893. X        outfab = (struct FAB *) extract_block(blk, 0,
  894. X                        &cc$rms_fab, FABL);
  895. X        }
  896. X        else if (EQL_L(block_id, XALLSIG))
  897. X        {
  898. X        xaball = (struct XABALL *) extract_block(blk, 0, 
  899. X                        &cc$rms_xaball, XALLL);
  900. X        LINK(xaball);
  901. X        }
  902. X        else if (EQL_L(block_id, XKEYSIG))
  903. X        {
  904. X        xabkey = (struct XABKEY *) extract_block(blk, 0,
  905. X                        &cc$rms_xabkey, XKEYL);
  906. X        LINK(xabkey);
  907. X        }
  908. X        else if (EQL_L(block_id, XFHCSIG))
  909. X        {
  910. X        xabfhc = (struct XABFHC *) extract_block(blk, 0,
  911. X                        &cc$rms_xabfhc, XFHCL);
  912. X        LINK(xabfhc);
  913. X        }
  914. X        else if (EQL_L(block_id, XDATSIG))
  915. X        {
  916. X        xabdat = (struct XABDAT *) extract_block(blk, 0,
  917. X                        &cc$rms_xabdat, XDATL);
  918. X        LINK(xabdat);
  919. X        }
  920. X        else if (EQL_L(block_id, XRDTSIG))
  921. X        {
  922. X        xabrdt = (struct XABRDT *) extract_block(blk, 0,
  923. X                        &cc$rms_xabrdt, XRDTL);
  924. X        /*    LINK(xabrdt);    -- Do not link xabrdt    */
  925. X        }
  926. X        else if (EQL_L(block_id, XPROSIG))
  927. X        {
  928. X        xabpro = (struct XABPRO *) extract_block(blk, 0,
  929. X                        &cc$rms_xabpro, XPROL);
  930. X        /*    LINK(xabpro);    -- Do not link xabpro
  931. X                       until close */
  932. X        }
  933. X        else if (EQL_L(block_id, VERSIG))
  934. X        {
  935. X        char verbuf[80];
  936. X        int verlen = 0;
  937. X        int vl = 0;
  938. X        int item = SYI$_VERSION;
  939. X        $DESCRIPTOR(version, verbuf);
  940. X        byte *vers;
  941. X
  942. X        lib$getsyi(&item, 0, &version, &verlen, 0, 0);
  943. X        verbuf[verlen] = 0;
  944. X        vers = extract_block(blk, &vl, 0, 0);
  945. X        if (strncmp(verbuf, vers, verlen))
  946. X        {
  947. X            printf("[ Warning: VMS version mismatch.");
  948. X
  949. X            printf("   This version %s --", verbuf);
  950. X            strncpy(verbuf, vers, vl);
  951. X            verbuf[vl] = 0;
  952. X            printf(" version made by %s ]\n", verbuf);
  953. X        }
  954. X        free(vers);
  955. X        }
  956. X        else
  957. X        fprintf(stderr, "[ Warning: Unknown block signature %s ]\n",
  958. X            block_id);
  959. X    }
  960. X    len -= blk->size + 4;
  961. X    scan += blk->size + 4;
  962. X    }
  963. X    if (outfab != 0)
  964. X    {
  965. X    outfab->fab$l_xab = first_xab;
  966. X    return 1;
  967. X    }
  968. X    else
  969. X    return 0;
  970. X}
  971. X
  972. X/******************************
  973. X *   Function extract_block   *
  974. X ******************************/
  975. X/*
  976. X *  Simple uncompression routne. The compression uses bit stream.
  977. X *  Compression scheme:
  978. X *
  979. X *  if(byte!=0)
  980. X *      putbit(1),putyte(byte)
  981. X *  else
  982. X *    putbit(0)
  983. X */
  984. Xstatic byte *extract_block(p, retlen, init, needlen)
  985. X    int *retlen;
  986. Xstruct extra_block *p;
  987. Xbyte *init;
  988. Xint needlen;
  989. X{
  990. X    byte *block;        /* Pointer to block allocated */
  991. X    byte *bitptr;        /* Pointer into compressed data */
  992. X    byte *outptr;        /* Pointer into output block */
  993. X    UWORD length;
  994. X    ULONG bitbuf = 0;
  995. X    int bitcnt = 0;
  996. X
  997. X#define _FILL     if(bitcnt+8 <= 32)            \
  998. X        {    bitbuf |= (*bitptr++) << bitcnt;\
  999. X            bitcnt += 8;            \
  1000. X        }
  1001. X
  1002. X
  1003. X    if( p->flags & 1 )
  1004. X    length = p->length;    /* Block is compressed */
  1005. X    else
  1006. X        length = p->size - EXTBSL - RESL;    /* Simple case, uncompressed */
  1007. X
  1008. X    if( needlen == 0 )
  1009. X    needlen = length;
  1010. X
  1011. X    if(retlen)
  1012. X    *retlen = needlen;
  1013. X
  1014. X    if( (p->flags & 1) || (needlen > length) )
  1015. X    {    if ((block = (byte*)malloc(needlen)) == NULL)
  1016. X        return NULL;
  1017. X    }
  1018. X/*
  1019. X    else if( needlen > length )
  1020. X    {    if ((block = (byte*)malloc(needlen)) == NULL)
  1021. X        return NULL;
  1022. X    }
  1023. X*/
  1024. X    else outptr = block = &p->body[0];
  1025. X
  1026. X    if(init && (length < needlen))
  1027. X    memcpy(block,init,needlen);
  1028. X
  1029. X    if ((p->flags & 1) == 0)
  1030. X    return block;        /* Do nothing more if uncompressed */
  1031. X
  1032. X    outptr = block;
  1033. X    bitptr = &p->body[0];
  1034. X
  1035. X    if(length > needlen)
  1036. X    length = needlen;
  1037. X
  1038. X    while (length--)
  1039. X    {
  1040. X    if (bitcnt <= 0)
  1041. X        _FILL;
  1042. X
  1043. X    if (bitbuf & 1)
  1044. X    {
  1045. X        bitbuf >>= 1;
  1046. X        if ((bitcnt -= 1) < 8)
  1047. X        _FILL;
  1048. X        *outptr++ = (byte) bitbuf;
  1049. X        bitcnt -= 8;
  1050. X        bitbuf >>= 8;
  1051. X    }
  1052. X    else
  1053. X    {
  1054. X        *outptr++ = 0;
  1055. X        bitcnt -= 1;
  1056. X        bitbuf >>= 1;
  1057. X    }
  1058. X    }
  1059. X    return block;
  1060. X}
  1061. X
  1062. X/***************************/
  1063. X/*  Function FlushOutput() */
  1064. X/***************************/
  1065. X
  1066. Xint FlushOutput()
  1067. X{                /* return PK-type error code */
  1068. X    /* flush contents of output buffer */
  1069. X    if (tflag)
  1070. X    {                /* Do not output. Update CRC only */
  1071. X    UpdateCRC(outbuf, outcnt);
  1072. X    outpos += outcnt;
  1073. X    outcnt = 0;
  1074. X    outptr = outbuf;
  1075. X    return 0;
  1076. X    }
  1077. X    else
  1078. X    return text_file ? _flush_records(0) : _flush_blocks(0);
  1079. X}
  1080. X
  1081. Xstatic int _flush_blocks(final_flag)    /* Asynchronous version */
  1082. X  int final_flag;
  1083. X/* 1 if this is the final flushout */
  1084. X{
  1085. X    int round;
  1086. X    int rest;
  1087. X    int off = 0;
  1088. X    int out_count = outcnt;
  1089. X    int status;
  1090. X
  1091. X    while(out_count > 0)
  1092. X    {    if( curbuf -> bufcnt < BUFS512 )
  1093. X    {    int ncpy;
  1094. X        ncpy = out_count > (BUFS512-curbuf->bufcnt) ? 
  1095. X                BUFS512-curbuf->bufcnt : 
  1096. X                out_count;
  1097. X        memcpy(curbuf->buf + curbuf->bufcnt, outbuf+off, ncpy);
  1098. X        out_count -= ncpy;
  1099. X        curbuf -> bufcnt += ncpy;
  1100. X        off += ncpy;
  1101. X    }        
  1102. X    if( curbuf -> bufcnt == BUFS512 )
  1103. X    {
  1104. X        status = WriteBuffer(curbuf->buf,curbuf->bufcnt);
  1105. X        if(status)
  1106. X            return status;
  1107. X        curbuf = curbuf -> next;
  1108. X        curbuf -> bufcnt = 0;
  1109. X    }
  1110. X    }
  1111. X
  1112. X    UpdateCRC(outbuf, outcnt);
  1113. X    outpos += outcnt;
  1114. X    outcnt = 0;
  1115. X    outptr = outbuf;
  1116. X
  1117. X    return (final_flag && (curbuf->bufcnt > 0)) ? 
  1118. X        WriteBuffer(curbuf->buf,curbuf->bufcnt) :
  1119. X    0;    /* 0:  no error */
  1120. X}
  1121. X
  1122. X#define RECORD_END(c)    ((c) == CR || (c) == LF)
  1123. X
  1124. Xstatic int _flush_records(final_flag)
  1125. X  int final_flag;
  1126. X/* 1 if this is the final flushout */
  1127. X{
  1128. X    int rest;
  1129. X    int end = 0, start = 0;
  1130. X    int off = 0;
  1131. X
  1132. X    if (outcnt == 0 && loccnt == 0)
  1133. X    return 0;        /* Nothing to do ... */
  1134. X
  1135. X    if (loccnt)
  1136. X    {
  1137. X    for (end = 0; end < outcnt && !RECORD_END(outbuf[end]);)
  1138. X        ++end;
  1139. X    if (end >= outcnt)
  1140. X    {
  1141. X        fprintf(stderr, "[ Warning: Record too long (%d) ]\n",
  1142. X            outcnt + loccnt);
  1143. X        if (WriteRecord(locbuf, loccnt))
  1144. X        return (50);
  1145. X        memcpy(locbuf, outbuf, outcnt);
  1146. X        locptr = &locbuf[loccnt = outcnt];
  1147. X    }
  1148. X    else
  1149. X    {
  1150. X        memcpy(locptr, outbuf, end);
  1151. X        if (WriteRecord(locbuf, loccnt + end))
  1152. X        return (50);
  1153. X        loccnt = 0;
  1154. X        locptr = &locbuf;
  1155. X    }
  1156. X    start = end + 1;
  1157. X    }
  1158. X
  1159. X    do
  1160. X    {
  1161. X    while (start < outcnt && outbuf[start] == CR)    /* Skip CR's at the
  1162. X                            *  beginning of rec. */
  1163. X        ++start;
  1164. X    /* Find record end */
  1165. X    for (end = start; end < outcnt && !RECORD_END(outbuf[end]);)
  1166. X        ++end;
  1167. X
  1168. X    if (end < outcnt)
  1169. X    {            /* Record end found, write the record */
  1170. X        if (WriteRecord(outbuf + start, end - start))
  1171. X        return (50);
  1172. X        /* Shift to the begining of the next record */
  1173. X        start = end + 1;
  1174. X    }
  1175. X    } while (start < outcnt && end < outcnt);
  1176. X
  1177. X    rest = outcnt - start;
  1178. X
  1179. X    if (rest > 0)
  1180. X    if (final_flag)
  1181. X    {
  1182. X        /* This is a final flush. Put out all remaining in
  1183. X        *  the buffer                */
  1184. X        if (loccnt && WriteRecord(locbuf, loccnt))
  1185. X        return (50);
  1186. X    }
  1187. X    else
  1188. X    {
  1189. X        memcpy(locptr, outbuf + start, rest);
  1190. X        locptr += rest;
  1191. X        loccnt += rest;
  1192. X    }
  1193. X    UpdateCRC(outbuf, outcnt);
  1194. X    outpos += outcnt;
  1195. X    outcnt = 0;
  1196. X    outptr = outbuf;
  1197. X    return (0);            /* 0:  no error */
  1198. X}
  1199. X
  1200. X/***************************/
  1201. X/*  Function WriteBuffer() */
  1202. X/***************************/
  1203. X
  1204. Xstatic int WriteBuffer(buf, len)/* return 0 if successful, 1 if not */
  1205. X  unsigned char *buf;
  1206. Xint len;
  1207. X{
  1208. X    int status;
  1209. X
  1210. X    status = sys$wait(outrab);
  1211. X#ifdef DEBUG
  1212. X    if(ERR(status))
  1213. X    {    message("[ Write buffer: sys$wait faled ]\n",status);
  1214. X    message("",outrab->rab$l_sts);
  1215. X    message("",outrab->rab$l_sts);
  1216. X    }
  1217. X#endif
  1218. X    outrab->rab$w_rsz = len;
  1219. X    outrab->rab$l_rbf = buf;
  1220. X
  1221. X    if (ERR(status = sys$write(outrab)))
  1222. X    {
  1223. X    fprintf(stderr, "WriteBuffer: sys$write failed.\n",
  1224. X        filename);
  1225. X    fprintf(stderr, "                    status = %d\n", status);
  1226. X    fprintf(stderr, "                  rab->sts = %d\n", outrab->rab$l_sts);
  1227. X    fprintf(stderr, "                       stv = %d\n", outrab->rab$l_stv);
  1228. X    return 50;
  1229. X    }
  1230. X    return (0);
  1231. X}
  1232. X
  1233. X/***************************/
  1234. X/*  Function WriteRecord() */
  1235. X/***************************/
  1236. X
  1237. Xstatic int WriteRecord(rec, len)/* return 0 if successful, 1 if not */
  1238. X  unsigned char *rec;
  1239. Xint len;
  1240. X{
  1241. X    int status;
  1242. X
  1243. X    sys$wait(outrab);
  1244. X#ifdef DEBUG
  1245. X    if(ERR(status))
  1246. X    {    message("[ Write buffer: sys$wait faled ]\n",status);
  1247. X    message("",outrab->rab$l_sts);
  1248. X    message("",outrab->rab$l_sts);
  1249. X    }
  1250. X#endif
  1251. X    outrab->rab$w_rsz = len;
  1252. X    outrab->rab$l_rbf = rec;
  1253. X
  1254. X    if (ERR(status = sys$put(outrab)))
  1255. X    {
  1256. X    fprintf(stderr, "WriteRecord: sys$put failed.\n",
  1257. X        filename);
  1258. X    fprintf(stderr, "                    status = %d\n", status);
  1259. X    fprintf(stderr, "                  rab->sts = %d\n", outrab->rab$l_sts);
  1260. X    fprintf(stderr, "                       stv = %d\n", outrab->rab$l_stv);
  1261. X    return 50;
  1262. X    }
  1263. X    return (0);
  1264. X}
  1265. X
  1266. X/********************************/
  1267. X/*  Function CloseOutputFile()  */
  1268. X/********************************/
  1269. X
  1270. Xint CloseOutputFile()
  1271. X{
  1272. X    int status;
  1273. X
  1274. X    if (text_file) _flush_records(1);
  1275. X    else
  1276. X    _flush_blocks(1);
  1277. X
  1278. X    if ((outfab->fab$l_xab = xabrdt) != 0L)    /* Link XABPRO and XABRDT */
  1279. X    xabrdt->xab$l_nxt = (secinf ? xabpro : 0L);
  1280. X    else
  1281. X    outfab->fab$l_xab = (secinf ? xabpro : 0L);
  1282. X
  1283. X    sys$wait(outrab);
  1284. X
  1285. X    status = sys$close(outfab);
  1286. X#ifdef DEBUG
  1287. X    if (ERR(status))
  1288. X    {
  1289. X    message("\r[ Warning: can not set owner/protection/time attributes ]\n", status);
  1290. X    message("", outfab->fab$l_stv);
  1291. X    }
  1292. X#endif
  1293. X}
  1294. X
  1295. X#ifdef DEBUG
  1296. Xdump_rms_block(p)
  1297. X  unsigned char *p;
  1298. X{
  1299. X    unsigned char bid, len;
  1300. X    int err;
  1301. X    char *type;
  1302. X    char buf[132];
  1303. X    int i;
  1304. X
  1305. X    err = 0;
  1306. X    bid = p[0];
  1307. X    len = p[1];
  1308. X    switch (bid)
  1309. X    {
  1310. X    case FAB$C_BID:
  1311. X        type = "FAB";
  1312. X        break;
  1313. X    case XAB$C_ALL:
  1314. X        type = "xabALL";
  1315. X        break;
  1316. X    case XAB$C_KEY:
  1317. X        type = "xabKEY";
  1318. X        break;
  1319. X    case XAB$C_DAT:
  1320. X        type = "xabDAT";
  1321. X        break;
  1322. X    case XAB$C_RDT:
  1323. X        type = "xabRDT";
  1324. X        break;
  1325. X    case XAB$C_FHC:
  1326. X        type = "xabFHC";
  1327. X        break;
  1328. X    case XAB$C_PRO:
  1329. X        type = "xabPRO";
  1330. X        break;
  1331. X    default:
  1332. X        type = "Unknown";
  1333. X        err = 1;
  1334. X        break;
  1335. X    }
  1336. X    printf("Block @%08X of type %s (%d).", p, type, bid);
  1337. X    if (err)
  1338. X    {
  1339. X    printf("\n");
  1340. X    return;
  1341. X    }
  1342. X    printf(" Size = %d\n", len);
  1343. X    printf(" Offset - Hex - Dec\n");
  1344. X    for (i = 0; i < len; i += 8)
  1345. X    {
  1346. X    int j;
  1347. X    printf("%3d - ", i);
  1348. X    for (j = 0; j < 8; j++)
  1349. X        if (i + j < len)
  1350. X        printf("%02X ", p[i + j]);
  1351. X        else
  1352. X        printf("   ");
  1353. X    printf(" - ");
  1354. X    for (j = 0; j < 8; j++)
  1355. X        if (i + j < len)
  1356. X        printf("%03d ", p[i + j]);
  1357. X        else
  1358. X        printf("    ");
  1359. X    printf("\n");
  1360. X    }
  1361. X}
  1362. X
  1363. X#endif                /* DEBUG */
  1364. X
  1365. Xmessage(string, status)
  1366. X    int status;
  1367. Xchar *string;
  1368. X{
  1369. X    char msgbuf[256];
  1370. X    $DESCRIPTOR(msgd, msgbuf);
  1371. X    int msglen = 0;
  1372. X
  1373. X    if (ERR(lib$sys_getmsg(&status, &msglen, &msgd, 0, 0)))
  1374. X    fprintf(stderr, "%s[ VMS status = %d ]\n", string, status);
  1375. X    else
  1376. X    {
  1377. X    msgbuf[msglen] = 0;
  1378. X    fprintf(stderr, "%s[ %s ]\n", string, msgbuf);
  1379. X    }
  1380. X}
  1381. X
  1382. X
  1383. X#endif                /* !VMS */
  1384. END_OF_FILE
  1385.   if test 20178 -ne `wc -c <'VMS/vms.c'`; then
  1386.     echo shar: \"'VMS/vms.c'\" unpacked with wrong size!
  1387.   fi
  1388.   # end of 'VMS/vms.c'
  1389. fi
  1390. if test -f 'unimplod.c' -a "${1}" != "-c" ; then 
  1391.   echo shar: Will not clobber existing file \"'unimplod.c'\"
  1392. else
  1393.   echo shar: Extracting \"'unimplod.c'\" \(9343 characters\)
  1394.   sed "s/^X//" >'unimplod.c' <<'END_OF_FILE'
  1395. X/*---------------------------------------------------------------------------
  1396. X
  1397. X  unimplod.c
  1398. X
  1399. X  The Imploding algorithm is actually a combination of two distinct algor-
  1400. X  ithms.  The first algorithm compresses repeated byte sequences using a
  1401. X  sliding dictionary.  The second algorithm is used to compress the encoding
  1402. X  of the sliding dictionary ouput, using multiple Shannon-Fano trees.
  1403. X
  1404. X  ---------------------------------------------------------------------------
  1405. X
  1406. X  Copyrights:  see accompanying file "COPYING" in UnZip source distribution.
  1407. X
  1408. X  ---------------------------------------------------------------------------*/
  1409. X
  1410. X
  1411. X#include "unzip.h"
  1412. X
  1413. X
  1414. X/***********************/
  1415. X/*  UnImplode Defines */
  1416. X/***********************/
  1417. X
  1418. X#define LITVALS     256
  1419. X#define DISTVALS    64
  1420. X#define LENVALS     64
  1421. X#define MAXSF       LITVALS
  1422. X
  1423. X
  1424. X
  1425. X/************************/
  1426. X/*  UnImplode Typedefs */
  1427. X/************************/
  1428. X
  1429. Xtypedef struct sf_entry {
  1430. X    byte Value;
  1431. X    byte BitLength;
  1432. X} sf_entry;
  1433. X
  1434. Xtypedef struct sf_tree {        /* a shannon-fano "tree" (table) */
  1435. X    sf_entry entry[MAXSF];
  1436. X    int entries;
  1437. X    int MaxLength;
  1438. X} sf_tree;
  1439. X
  1440. Xtypedef struct sf_node {        /* node in a true shannon-fano tree */
  1441. X    UWORD left;                 /* 0 means leaf node */
  1442. X    UWORD right;                /*   or value if leaf node */
  1443. X} sf_node;
  1444. X
  1445. X
  1446. X
  1447. X/********************************/
  1448. X/*  UnImplode Global Variables */
  1449. X/********************************/
  1450. X
  1451. X/* s-f storage is shared with that used by other comp. methods */
  1452. X
  1453. Xsf_tree lit_tree;
  1454. Xsf_tree length_tree;
  1455. Xsf_tree distance_tree;
  1456. Xsf_node *lit_nodes = (sf_node *) prefix_of;     /* 2*LITVALS nodes */
  1457. X#ifdef MACOS
  1458. Xsf_node *length_nodes ;  /* 2*LENVALS nodes */
  1459. Xsf_node *distance_nodes ;    /* 2*DISTVALS nodes */
  1460. X#else
  1461. Xsf_node *length_nodes = (sf_node *) suffix_of;  /* 2*LENVALS nodes */
  1462. Xsf_node *distance_nodes = (sf_node *) stack;    /* 2*DISTVALS nodes */
  1463. X#endif
  1464. Xboolean lit_tree_present;
  1465. Xboolean eightK_dictionary;
  1466. Xint minimum_match_length;
  1467. Xint dict_bits;
  1468. X
  1469. X
  1470. X
  1471. X/*****************************************/
  1472. X/*  UnImplode Local Function Prototypes */
  1473. X/*****************************************/
  1474. X
  1475. Xstatic void LoadTrees __((void));
  1476. Xstatic void LoadTree __((sf_tree * tree, int treesize, sf_node * nodes));
  1477. Xstatic void ReadLengths __((sf_tree * tree));
  1478. Xstatic void SortLengths __((sf_tree * tree));
  1479. Xstatic void GenerateTrees __((sf_tree * tree, sf_node * nodes));
  1480. Xstatic void ReadTree __((register sf_node * nodes, int *dest));
  1481. X
  1482. X
  1483. X
  1484. X
  1485. X
  1486. X/**************************/
  1487. X/*  Function unImplode() */
  1488. X/**************************/
  1489. X
  1490. Xvoid unImplode()
  1491. X /* expand imploded data */
  1492. X{
  1493. X    register int srcix;
  1494. X    register int Length;
  1495. X    register int limit;
  1496. X    int lout;
  1497. X    int Distance;
  1498. X
  1499. X    LoadTrees();
  1500. X
  1501. X#ifdef DEBUG
  1502. X    printf("\n");
  1503. X#endif
  1504. X    while ((!zipeof) && ((outpos + outcnt) < ucsize)) {
  1505. X        READBIT(1, lout);
  1506. X
  1507. X        if (lout != 0) {        /* encoded data is literal data */
  1508. X            if (lit_tree_present) {     /* use Literal Shannon-Fano tree */
  1509. X                ReadTree(lit_nodes, &lout);
  1510. X#ifdef DEBUG
  1511. X                printf("lit=%d\n", lout);
  1512. X#endif
  1513. X            } else
  1514. X                READBIT(8, lout);
  1515. X
  1516. X            OUTB(lout);
  1517. X        } else {                /* encoded data is sliding dictionary match */
  1518. X            READBIT(dict_bits, Distance);
  1519. X
  1520. X            ReadTree(distance_nodes, &lout);
  1521. X#ifdef DEBUG
  1522. X            printf("d=%5d (%2d,%3d)", (lout << dict_bits) | Distance, lout,
  1523. X                   Distance);
  1524. X#endif
  1525. X            Distance |= (lout << dict_bits);
  1526. X            /* using the Distance Shannon-Fano tree, read and decode the
  1527. X               upper 6 bits of the Distance value */
  1528. X
  1529. X            ReadTree(length_nodes, &lout);
  1530. X            Length = lout;
  1531. X#ifdef DEBUG
  1532. X            printf("\tl=%3d\n", Length);
  1533. X#endif
  1534. X            /* using the Length Shannon-Fano tree, read and decode the
  1535. X               Length value */
  1536. X
  1537. X            if (Length == 63) {
  1538. X                READBIT(8, lout);
  1539. X                Length += lout;
  1540. X            }
  1541. X            Length += minimum_match_length;
  1542. X
  1543. X            /* move backwards Distance+1 bytes in the output stream, and copy
  1544. X              Length characters from this position to the output stream.
  1545. X              (if this position is before the start of the output stream,
  1546. X              then assume that all the data before the start of the output
  1547. X              stream is filled with zeros.  Requires initializing outbuf
  1548. X              for each file.) */
  1549. X
  1550. X            srcix = (outcnt - (Distance + 1)) & (OUTBUFSIZ - 1);
  1551. X            limit = OUTBUFSIZ - Length;
  1552. X            if ((srcix <= limit) && (outcnt < limit)) {
  1553. X                outcnt += Length;
  1554. X                while (Length--)
  1555. X                    *outptr++ = outbuf[srcix++];
  1556. X            } else {
  1557. X                while (Length--) {
  1558. X                    OUTB(outbuf[srcix++]);
  1559. X                    srcix &= OUTBUFSIZ - 1;
  1560. X                }
  1561. X            }
  1562. X        }
  1563. X    }
  1564. X}
  1565. X
  1566. X
  1567. X
  1568. X
  1569. X
  1570. X/**************************/
  1571. X/*  Function LoadTrees() */
  1572. X/**************************/
  1573. X
  1574. Xstatic void LoadTrees()
  1575. X{
  1576. X    eightK_dictionary = (lrec.general_purpose_bit_flag & 0x02) != 0;    /* bit 1 */
  1577. X    lit_tree_present = (lrec.general_purpose_bit_flag & 0x04) != 0;     /* bit 2 */
  1578. X
  1579. X    if (eightK_dictionary)
  1580. X        dict_bits = 7;
  1581. X    else
  1582. X        dict_bits = 6;
  1583. X
  1584. X    if (lit_tree_present) {
  1585. X        minimum_match_length = 3;
  1586. X        LoadTree(&lit_tree, 256, lit_nodes);
  1587. X    } else
  1588. X        minimum_match_length = 2;
  1589. X
  1590. X    LoadTree(&length_tree, 64, length_nodes);
  1591. X    LoadTree(&distance_tree, 64, distance_nodes);
  1592. X}
  1593. X
  1594. X
  1595. X
  1596. X
  1597. X
  1598. X/*************************/
  1599. X/*  Function LoadTree() */
  1600. X/*************************/
  1601. X
  1602. Xstatic void LoadTree(tree, treesize, nodes)
  1603. Xsf_tree *tree;
  1604. Xint treesize;
  1605. Xsf_node *nodes;
  1606. X /* allocate and load a shannon-fano tree from the compressed file */
  1607. X{
  1608. X    tree->entries = treesize;
  1609. X    ReadLengths(tree);
  1610. X    SortLengths(tree);
  1611. X    GenerateTrees(tree, nodes);
  1612. X}
  1613. X
  1614. X
  1615. X
  1616. X
  1617. X
  1618. X/****************************/
  1619. X/*  Function ReadLengths() */
  1620. X/****************************/
  1621. X
  1622. Xstatic void ReadLengths(tree)
  1623. Xsf_tree *tree;
  1624. X{
  1625. X    int treeBytes;
  1626. X    int i;
  1627. X    int num, len;
  1628. X
  1629. X    /* get number of bytes in compressed tree */
  1630. X    READBIT(8, treeBytes);
  1631. X    treeBytes++;
  1632. X    i = 0;
  1633. X
  1634. X    tree->MaxLength = 0;
  1635. X
  1636. X/* High 4 bits: Number of values at this bit length + 1. (1 - 16)
  1637. X * Low  4 bits: Bit Length needed to represent value + 1. (1 - 16)
  1638. X */
  1639. X    while (treeBytes > 0) {
  1640. X        READBIT(4, len);
  1641. X        len++;
  1642. X        READBIT(4, num);
  1643. X        num++;
  1644. X
  1645. X        while (num > 0) {
  1646. X            if (len > tree->MaxLength)
  1647. X                tree->MaxLength = len;
  1648. X            tree->entry[i].BitLength = len;
  1649. X            tree->entry[i].Value = i;
  1650. X            i++;
  1651. X            num--;
  1652. X        }
  1653. X
  1654. X        treeBytes--;
  1655. X    }
  1656. X}
  1657. X
  1658. X
  1659. X
  1660. X
  1661. X
  1662. X/****************************/
  1663. X/*  Function SortLengths() */
  1664. X/****************************/
  1665. X
  1666. Xstatic void SortLengths(tree)
  1667. Xsf_tree *tree;
  1668. X /* Sort the Bit Lengths in ascending order, while retaining the order
  1669. X   of the original lengths stored in the file */
  1670. X{
  1671. X    register sf_entry *ejm1;    /* entry[j - 1] */
  1672. X    register int j;
  1673. X    register sf_entry *entry;
  1674. X    register int i;
  1675. X    sf_entry tmp;
  1676. X    int entries;
  1677. X    unsigned a, b;
  1678. X
  1679. X    entry = &tree->entry[0];
  1680. X    entries = tree->entries;
  1681. X
  1682. X    for (i = 0; ++i < entries;) {
  1683. X        tmp = entry[i];
  1684. X        b = tmp.BitLength;
  1685. X        j = i;
  1686. X        while ((j > 0)
  1687. X               && ((a = (ejm1 = &entry[j - 1])->BitLength) >= b)) {
  1688. X            if ((a == b) && (ejm1->Value <= tmp.Value))
  1689. X                break;
  1690. X            *(ejm1 + 1) = *ejm1;/* entry[j] = entry[j - 1] */
  1691. X            --j;
  1692. X        }
  1693. X        entry[j] = tmp;
  1694. X    }
  1695. X}
  1696. X
  1697. X
  1698. X
  1699. X
  1700. X
  1701. X/******************************/
  1702. X/*  Function GenerateTrees() */
  1703. X/******************************/
  1704. X
  1705. Xstatic void GenerateTrees(tree, nodes)
  1706. Xsf_tree *tree;
  1707. Xsf_node *nodes;
  1708. X /* Generate the Shannon-Fano trees */
  1709. X{
  1710. X    int codelen, i, j, lvlstart, next, parents;
  1711. X
  1712. X    i = tree->entries - 1;      /* either 255 or 63 */
  1713. X    lvlstart = next = 1;
  1714. X
  1715. X    /* believe it or not, there may be a 1-bit code */
  1716. X
  1717. X    for (codelen = tree->MaxLength; codelen >= 1; --codelen) {
  1718. X
  1719. X        /* create leaf nodes at level <codelen> */
  1720. X
  1721. X        while ((i >= 0) && (tree->entry[i].BitLength == codelen)) {
  1722. X            nodes[next].left = 0;
  1723. X            nodes[next].right = tree->entry[i].Value;
  1724. X            ++next;
  1725. X            --i;
  1726. X        }
  1727. X
  1728. X        /* create parent nodes for all nodes at level <codelen>,
  1729. X           but don't create the root node here */
  1730. X
  1731. X        parents = next;
  1732. X        if (codelen > 1) {
  1733. X            for (j = lvlstart; j <= parents - 2; j += 2) {
  1734. X                nodes[next].left = j;
  1735. X                nodes[next].right = j + 1;
  1736. X                ++next;
  1737. X            }
  1738. X        }
  1739. X        lvlstart = parents;
  1740. X    }
  1741. X
  1742. X    /* create root node */
  1743. X
  1744. X    nodes[0].left = next - 2;
  1745. X    nodes[0].right = next - 1;
  1746. X}
  1747. X
  1748. X
  1749. X
  1750. X
  1751. X
  1752. X/************************/
  1753. X/*  Function ReadTree() */
  1754. X/************************/
  1755. X
  1756. X#ifndef ASM
  1757. X
  1758. Xstatic void ReadTree(nodes, dest)
  1759. Xregister sf_node *nodes;
  1760. Xint *dest;
  1761. X /* read next byte using a shannon-fano tree */
  1762. X{
  1763. X    register int cur;
  1764. X    register int left;
  1765. X    UWORD b;
  1766. X
  1767. X    for (cur = 0;;) {
  1768. X        if ((left = nodes[cur].left) == 0) {
  1769. X            *dest = nodes[cur].right;
  1770. X            return;
  1771. X        }
  1772. X        READBIT(1, b);
  1773. X        cur = (b ? nodes[cur].right : left);
  1774. X    }
  1775. X}
  1776. X
  1777. X#endif                          /* !ASM */
  1778. END_OF_FILE
  1779.   if test 9343 -ne `wc -c <'unimplod.c'`; then
  1780.     echo shar: \"'unimplod.c'\" unpacked with wrong size!
  1781.   fi
  1782.   # end of 'unimplod.c'
  1783. fi
  1784. echo shar: End of archive 8 \(of 12\).
  1785. cp /dev/null ark8isdone
  1786. MISSING=""
  1787. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  1788.     if test ! -f ark${I}isdone ; then
  1789.     MISSING="${MISSING} ${I}"
  1790.     fi
  1791. done
  1792. if test "${MISSING}" = "" ; then
  1793.     echo You have unpacked all 12 archives.
  1794.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1795. else
  1796.     echo You still must unpack the following archives:
  1797.     echo "        " ${MISSING}
  1798. fi
  1799. exit 0
  1800. exit 0 # Just in case...
  1801.