home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2218 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  49.8 KB

  1. From: davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr)
  2. Newsgroups: alt.sources
  3. Subject: lharc for unix (02/02)
  4. Message-ID: <3007@crdos1.crd.ge.COM>
  5. Date: 6 Dec 90 15:03:45 GMT
  6.  
  7. #!/bin/sh
  8. # this is part 2 of a multipart archive
  9. # do not concatenate these parts, unpack them in order with /bin/sh
  10. # file lharc.c continued
  11. #
  12. CurArch=2
  13. if test ! -r s2_seq_.tmp
  14. then echo "Please unpack part 1 first!"
  15.      exit 1; fi
  16. ( read Scheck
  17.   if test "$Scheck" != $CurArch
  18.   then echo "Please unpack part $Scheck next!"
  19.        exit 1;
  20.   else exit 0; fi
  21. ) < s2_seq_.tmp || exit 1
  22. echo "x - Continuing file lharc.c"
  23. sed 's/^X//' << 'SHAR_EOF' >> lharc.c
  24. X    } else {
  25. X      fseek (fp, hdr.packed_size, SEEK_CUR);
  26. X    }
  27. X    }
  28. X
  29. X  fclose (fp);
  30. X
  31. X  return;
  32. X}
  33. X
  34. X/*----------------------------------------------------------------------*/
  35. X/*                                    */
  36. X/*----------------------------------------------------------------------*/
  37. X
  38. Xextern int encode_lzhuf ();
  39. Xextern int encode_storerd_crc ();
  40. X
  41. Xappend_one (fp, nafp, hdr)
  42. X     FILE *fp, *nafp;
  43. X     LzHeader *hdr;
  44. X{
  45. X  long    header_pos, next_pos, org_pos, data_pos;
  46. X  long    v_original_size, v_packed_size;
  47. X
  48. X  reading_filename = hdr->name;
  49. X  writting_filename = temporary_name;
  50. X
  51. X  org_pos = ftell (fp);
  52. X  header_pos = ftell (nafp);
  53. X  write_header (nafp, hdr);    /* DUMMY */
  54. X
  55. X  if (hdr->original_size == 0)
  56. X    {
  57. X      printf("%s - not frozen\n",hdr->name);
  58. X      return;        /* previous write_header is not DUMMY. (^_^) */
  59. X    }
  60. X
  61. X  data_pos = ftell (nafp);
  62. X  hdr->crc = encode_lzhuf (fp, nafp, hdr->original_size,
  63. X               &v_original_size, &v_packed_size, hdr->name);
  64. X  if (v_packed_size < v_original_size)
  65. X    {
  66. X      next_pos = ftell (nafp);
  67. X    }
  68. X  else
  69. X    {                /* retry by stored method */
  70. X      fseek (fp, org_pos, SEEK_SET);
  71. X      fseek (nafp, data_pos, SEEK_SET);
  72. X      hdr->crc = encode_stored_crc (fp, nafp, hdr->original_size,
  73. X                    &v_original_size, &v_packed_size);
  74. X      fflush (nafp);
  75. X      next_pos = ftell (nafp);
  76. X      ftruncate (fileno (nafp), next_pos);
  77. X      bcopy (LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE);
  78. X    }
  79. X  hdr->original_size = v_original_size;
  80. X  hdr->packed_size = v_packed_size;
  81. X  fseek (nafp, header_pos, SEEK_SET);
  82. X  write_header (nafp, hdr);
  83. X  fseek (nafp, next_pos, SEEK_SET);
  84. X}
  85. X
  86. Xwrite_tail (nafp)
  87. X     FILE *nafp;
  88. X{
  89. X  putc (0x00, nafp);
  90. X}
  91. X
  92. Xcopy_old_one (oafp, nafp, hdr)
  93. X     FILE *oafp, *nafp;
  94. X     LzHeader *hdr;
  95. X{
  96. X  if (noexec)
  97. X    {
  98. X      fseek (oafp, (long)(hdr->header_size + 2) + hdr->packed_size, SEEK_CUR);
  99. X    }
  100. X  else
  101. X    {
  102. X      reading_filename = archive_name;
  103. X      writting_filename = temporary_name;
  104. X      copy_file (oafp, nafp, (long)(hdr->header_size + 2) + hdr->packed_size);
  105. X    }
  106. X}
  107. X
  108. X
  109. XFILE *append_it (name, oafp, nafp)
  110. X     char *name;
  111. X     FILE *oafp, *nafp;
  112. X{
  113. X  LzHeader    ahdr, hdr;
  114. X  FILE        *fp;
  115. X  long        old_header;
  116. X  int        cmp;
  117. X  int        filec;
  118. X  char        **filev;
  119. X  int        i;
  120. X
  121. X  struct stat    v_stat;
  122. X  boolean    directory;
  123. X
  124. X  /* check that any added name is not the same as the archive name */
  125. X  if (strcmp(name, archive_name) == 0) return oafp;
  126. X
  127. X  if (!delete_from_archive)
  128. X    if (stat (name, &v_stat) < 0)
  129. X      {
  130. X        message ("Error:", name);
  131. X        return oafp;
  132. X      }
  133. X
  134. X  directory = ((v_stat.st_mode & S_IFMT) == S_IFDIR);
  135. X
  136. X  init_header (name, &v_stat, &hdr);
  137. X
  138. X  if (!delete_from_archive && !directory && !noexec)
  139. X    fp = xfopen (name, RMODE);
  140. X
  141. X  while (oafp)
  142. X    {
  143. X      old_header = ftell (oafp);
  144. X      if (!get_header (oafp, &ahdr))
  145. X    {
  146. X      fclose (oafp);
  147. X      oafp = NULL;
  148. X      break;
  149. X    }
  150. X      else
  151. X    {
  152. X      cmp = STRING_COMPARE (ahdr.name, hdr.name);
  153. X      if (cmp < 0)
  154. X        {        /* SKIP */
  155. X          fseek (oafp, old_header, SEEK_SET);
  156. X          copy_old_one (oafp, nafp, &ahdr);
  157. X        }
  158. X      else if (cmp == 0)
  159. X        {        /* REPLACE */
  160. X          fseek (oafp, ahdr.packed_size, SEEK_CUR);
  161. X          break;
  162. X        }
  163. X      else        /* cmp > 0, INSERT */
  164. X        {
  165. X          fseek (oafp, old_header, SEEK_SET);
  166. X          break;
  167. X        }
  168. X    }
  169. X    }
  170. X
  171. X  if (delete_from_archive)
  172. X    {
  173. X      if (noexec)
  174. X        fprintf (stderr, "DELETE %s\n", name);
  175. X      else
  176. X        printf ("%s - Deleted\n", name);
  177. X    }
  178. X  else
  179. X    {
  180. X      if ( !oafp || (cmp > 0) || !update_if_newer
  181. X           || (ahdr.unix_last_modified_stamp < hdr.unix_last_modified_stamp) )
  182. X    {
  183. X      if (noexec)
  184. X        fprintf (stderr, "APPEND %s\n", name);
  185. X          else
  186. X#ifdef STRICT
  187. X            if ( !directory )
  188. X#endif
  189. X              if ( !update_freshen || (cmp == 0) )
  190. X                append_one (fp, nafp, &hdr);
  191. X    }
  192. X      else
  193. X    {                    /* archive has old one */
  194. X      fseek (oafp, old_header, SEEK_SET);
  195. X      copy_old_one (oafp, nafp, &ahdr);
  196. X    }
  197. X
  198. X      if (!directory)
  199. X    {
  200. X      if (!noexec)
  201. X        fclose (fp);
  202. X    }
  203. X      else
  204. X    {            /* recurcive call */
  205. X      if (find_files (name, &filec, &filev))
  206. X        {
  207. X          for (i = 0; i < filec; i ++)
  208. X        oafp = append_it (filev[i], oafp, nafp);
  209. X          free_files (filec, filev);
  210. X        }
  211. X      return oafp;
  212. X    }
  213. X    }
  214. X
  215. X  return oafp;
  216. X}
  217. X
  218. X
  219. Xremove_it (name)
  220. X     char *name;
  221. X{
  222. X  struct stat    v_stat;
  223. X  int        i;
  224. X  char        **filev;
  225. X  int        filec;
  226. X
  227. X  if (stat (name, &v_stat) < 0)
  228. X    {
  229. X      fprintf (stderr, "Cannot access \"%s\".\n", name);
  230. X      return;
  231. X    }
  232. X
  233. X  if ((v_stat.st_mode & S_IFMT) == S_IFDIR)
  234. X    {
  235. X      if (!find_files (name, &filec, &filev))
  236. X    {
  237. X          fprintf (stderr, "Cannot open directory \"%s\".\n", name);
  238. X      return;
  239. X    }
  240. X
  241. X      for (i = 0; i < filec; i ++)
  242. X    remove_it (filev[i]);
  243. X
  244. X      free_files (filec, filev);
  245. X
  246. X      if (noexec)
  247. X        printf ("REMOVE DIR %s\n", name);
  248. X      else if (rmdir (name) < 0)
  249. X        fprintf (stderr, "Cannot remove directory \"%s\".\n", name);
  250. X      else if (!quiet)
  251. X        printf ("%s - Removed\n", name);
  252. X    }
  253. X  else
  254. X    {
  255. X      if (noexec)
  256. X        printf ("REMOVE %s\n", name);
  257. X      else if (unlink (name) < 0)
  258. X        fprintf (stderr, "Cannot delete \"%s\".\n", name);
  259. X      else if (!quiet)
  260. X        printf ("%s - Removed\n", name);
  261. X    }
  262. X}
  263. X
  264. X#ifdef FASTCOPY
  265. X#define BUFFER_SIZE 16384
  266. X
  267. X#ifndef O_BINARY
  268. X#define O_BINARY 0
  269. X#endif
  270. X
  271. Xcopy_archive(src, dst)
  272. Xchar *src;
  273. Xchar *dst;
  274. X{
  275. X  int ih, oh;
  276. X  unsigned chunk;
  277. X  char *buffer = (char *) rson;
  278. X
  279. X  printf ("Copying temp to archive ... ");
  280. X
  281. X  ih = open (src, O_RDONLY | O_BINARY);
  282. X  if ( ih == -1 )
  283. X    error(src);
  284. X  oh = open (dst, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  285. X  if ( oh == -1 )
  286. X    error(dst);
  287. X
  288. X  while ( (chunk = read(ih, buffer, BUFFER_SIZE)) > 0 )
  289. X    if ( write(oh, buffer, chunk) != chunk )
  290. X      error(dst);
  291. X
  292. X  close (ih);
  293. X  close (oh);
  294. X
  295. X  printf("\b\b\b\b   \b\b\b\b.\n");
  296. X}
  297. X#endif
  298. X
  299. Xcmd_append ()
  300. X{
  301. X  LzHeader    ahdr;
  302. X  FILE        *oafp, *nafp;
  303. X  char        backup_archive_name [ FILENAME_LENGTH ];
  304. X  char        new_archive_name_buffer [ FILENAME_LENGTH ];
  305. X  char        *new_archive_name;
  306. X  int        i;
  307. X  long        old_header;
  308. X  struct stat    v_stat;
  309. X  boolean    old_archive_exist;
  310. X
  311. X  if (cmd_filec == 0)
  312. X    return;
  313. X
  314. X  make_tmp_name (archive_name, temporary_name);
  315. X
  316. X  if ((oafp = fopen (archive_name, RMODE)) == NULL)
  317. X    if (expand_archive_name (expanded_archive_name, archive_name))
  318. X      {
  319. X    errno = 0;
  320. X        oafp = fopen (expanded_archive_name, RMODE);
  321. X    archive_name = expanded_archive_name;
  322. X      }
  323. X
  324. X  old_archive_exist = (oafp) ? TRUE : FALSE;
  325. X  if (new_archive && oafp)
  326. X    {
  327. X      fclose (oafp);
  328. X      oafp = NULL;
  329. X    }
  330. X
  331. X  if (oafp && archive_is_msdos_sfx1 (archive_name))
  332. X    {
  333. X      skip_msdos_sfx1_code (oafp);
  334. X      make_standard_archive_name (new_archive_name_buffer, archive_name);
  335. X      new_archive_name = new_archive_name_buffer;
  336. X    }
  337. X  else
  338. X    {
  339. X      new_archive_name = archive_name;
  340. X    }
  341. X
  342. X  errno = 0;
  343. X  if (!noexec)
  344. X    {
  345. X      nafp = xfopen (temporary_name, WMODE);
  346. X      remove_temporary_at_error = TRUE;
  347. X    }
  348. X
  349. X  for (i = 0; i < cmd_filec; i ++)
  350. X    oafp = append_it (cmd_filev[i], oafp, nafp);
  351. X
  352. X  if (oafp)
  353. X    {
  354. X      old_header = ftell (oafp);
  355. X      while (get_header (oafp, &ahdr))
  356. X    {
  357. X      fseek (oafp, old_header, SEEK_SET);
  358. X      copy_old_one (oafp, nafp, &ahdr);
  359. X      old_header = ftell (oafp);
  360. X    }
  361. X      fclose (oafp);
  362. X    }
  363. X
  364. X  if (!noexec)
  365. X    {
  366. X      write_tail (nafp);
  367. X      fclose (nafp);
  368. X    }
  369. X
  370. X  make_backup_name (backup_archive_name, archive_name);
  371. X
  372. X  if (!noexec && old_archive_exist)
  373. X  {
  374. X    unlink(backup_archive_name);
  375. X
  376. X    if (rename (archive_name, backup_archive_name) < 0)
  377. X      error (archive_name);
  378. X  }
  379. X
  380. X  if (!quiet && new_archive_name == new_archive_name_buffer)
  381. X    {                /* warning at old archive is SFX */
  382. X      printf ("New Archive File is \"%s\"\n", new_archive_name);
  383. X    }
  384. X
  385. X  if (!noexec && rename (temporary_name, new_archive_name) < 0)
  386. X    {
  387. X      if (stat (temporary_name, &v_stat) < 0)
  388. X    error (temporary_name);
  389. X
  390. X#ifdef FASTCOPY
  391. X      copy_archive(temporary_name, archive_name);
  392. X#else
  393. X      oafp = xfopen (temporary_name, RMODE);
  394. X      nafp = xfopen (archive_name, WMODE);
  395. X      reading_filename = temporary_name;
  396. X      writting_filename = archive_name;
  397. X      copy_file (oafp, nafp, (long)v_stat.st_size);
  398. X      fclose (nafp);
  399. X      fclose (oafp);
  400. X#endif
  401. X
  402. X      unlink (temporary_name);
  403. X    }
  404. X  remove_temporary_at_error = FALSE;
  405. X
  406. X  if (delete_after_append)
  407. X    {
  408. X      if (!quiet && !noexec)
  409. X    printf ("Erasing...\n");
  410. X      for (i = 0; i < cmd_filec; i ++)
  411. X    remove_it (cmd_filev[i]);
  412. X    }
  413. X
  414. X  return;
  415. X}
  416. X
  417. X/* XENIX kludges */
  418. X#ifdef M_XENIX
  419. Xrename(old, new)
  420. Xchar *old, *new;
  421. X{
  422. X    char cmd[256];
  423. X
  424. X    sprintf(cmd, "/bin/mv %s %s", old, new);
  425. X    system(cmd);
  426. X}
  427. X#endif    /* XENIX */
  428. SHAR_EOF
  429. echo "File lharc.c is complete"
  430. chmod 0666 lharc.c || echo "restore of lharc.c fails"
  431. echo "x - extracting lharc.doc (Text)"
  432. sed 's/^X//' << 'SHAR_EOF' > lharc.doc &&
  433. X------------------------------------------------------------------------------
  434. X            LHarc UNIX  Release #3  V0.03 beta version
  435. X            Copyright (C) 1989  Yooichi.Tagawa
  436. X
  437. X                        cl mj
  438. X                        z oMIX ID: y.tagawa
  439. X------------------------------------------------------------------------------
  440. X    1Lv
  441. X
  442. X    UNIX EL LHarc p
  443. X
  444. X
  445. X    H    :AAIfgH"),hAUNIX E LHarc (LHarc UNIX) p LHarc F
  446. X    *5\7B
  447. X
  448. X
  449. Xyg"{z
  450. X    lharc {axevludmcp}[qnft] archive_file [files or directories...]
  451. X
  452. X    R}hMAaxevludmcp L"Cj)PFBpwh5\7B(H*s    B)
  453. X    IvVM qnft )gp"-BE`wh    B\E7B
  454. X    (H*    B\B3
  455. X
  456. X
  457. XyA[JCut@C <z
  458. X    wh5=t@C <Lt@C *H/jNA.lzh pt@C <L ckIt
  459. X        A5D5\7B5=*AD;Lj
  460. X    AI KhM h\9q*A    ^pcATtBbNXF5D .lzh Ij7
  461. X    iL*G")F]\5")Fv"\7B
  462. X    .com (fQ .exe LTbtBNXLj
  463. X    3j= SFX ().W
  464. X    5\7B5)5ALHarc UNIX EMASFX  `.Lt@C p
  465. X    ME+\9qBSFX  `.LA[JCut@C IN5DG    A/
  466. X    =j
  467. X    
  468. X
  469. X
  470. XyR}hjz
  471. X    a        A[JCut@C Iwh5=t@C pG    A
  472. X        fB Ng
  473. X        WD
  474. X    x \=M e    A[JCut@C L)gwh5=t@C )7WDLt@
  475. X        C p
  476. X    v \=M l    A[JCut@C `I
  477. X        WDLt@C Ljp\&5\7Bl Lj
  478. X        qpoM5\7B
  479. X    u        wh5=t@C *A[JCut@C `I
  480. X        C fhV5")AA[JCut@C `I
  481. X        jN
  482. X    d        A[JCut@C L)gwh5=t@C p
  483. X    m        A[JCut@C Iwh5=t@C p
  484. X        5=t@C p
  485. X    c        A[JCut@C L`epj
  486. X         p
  487. X    p        A[JCut@C L)gwh5=t@C )7WDL`e
  488. X        pW
  489. X
  490. XyIvVjz
  491. X    q        bZ[WL}'p
  492. X    n        @
  493. X    f        
  494. X    t        eLXg[hBMS-DOS EELeLXgt@C L    |
  495. X        O
  496. X        dl*Omi)`5j\9qB)
  497. X
  498. X
  499. Xy ]
  500. X    MS-DOS LHarc V1.13c ( i"MA;jHO) E
  501. X    C F ]
  502. X    Z[W*oi)`5j\9qB
  503. X    LHarc UNIX E
  504. X    h*
  505. X
  506. X
  507. Xyzz Khz
  508. X    H    :Lp EA
  509. X
  510. X    1.  
  511. X    2.  zz`eIB"DMA
  512. X        a.  zzL
  513. X        v
  514. X        
  515. X        gppS7i1FB
  516. X        b.  LHarc IN7it    A    ?l*t/gjD
  517. X        jg`E+i>/
  518. X        t    A    ?l*t/gjD"i1Fp>&5=hLgppS
  519. X        7i1FB
  520. X        c.  oCi
  521. X    3.  
  522. X    4.  1Lv
  523. X        X5H"B
  524. X    5.  
  525. X            mH"B
  526. X    6.  1Lv
  527. X        p5D`)\mH"B1Lj
  528. X        H-ALHarc F<fADM"/H"B
  529. X    7.  $pI
  530. X        F_iB
  531. X        a.    1Lv
  532. X        b.    $pL
  533. X        =j
  534. X        c.    CXg[ LhiF5Dgp7ij
  535. X        $1Fp
  536. X        \=A;LF+L9
  537. X        d.    $ppt    A    ?lF5D
  538. X        $pRMA;LT|[gp
  539. X
  540. X
  541. Xy
  542. X    LZHUF @L
  543. X    ;jp Nifty IP    n5A\=ALArc L
  544. X    1jgLvv)g LZHUF @ yQAMS-DOS E LHarc p
  545. X    A
  546. X    N
  547. X    qI
  548. X
  549. X
  550. X
  551. XG L V0.03:
  552. X    *    1.  quiet F text_mode LIvVpt/D]\5=B
  553. X        text_mode LIvVMAdl*Omi)`5j\9qLE
  554. X        5DgAD->3"B
  555. X    2.  G    [bZ[W*sKXH* i)`5j\9qB
  556. X    +    3.  
  557. X        1qH`qE""LE5e$)B(^_^)
  558. X    +    4.  TufB Ng
  559. X        A[JCut@C IG    ALbhpFhL<-1F*E+\5=B
  560. X    *    5.  3k/W
  561. X         E7B LArc type 4  yQAtype 5 I`N    5\5=B
  562. X    *    6.  MS-DOS ELZ tGNXg    NgLA[JCu `.`    p
  563. X        $I5\5=B
  564. X    7.  MS-DOS E V1.13c LA[JCut@C * [MS-DOS] EH-A
  565. X        [generic] IHh\7*AMS-DOS ELLE =h(\*))gM
  566. X        [MS-DOS] FF/E+itH[}bgIHAD"iFv"\7B(^_^)
  567. X    8.  MS-DOS E V1.13c ELTufB Ng
  568. X        W
  569. X    9.  {M VAX 11/785 UNIX 4.2BSD E
  570. X        (`FbNRj* i)`5j\9q)
  571. X    +    10.  d66)Fv"\7*AMS-DOS <--> UNIX 
  572. X        L]MoCi
  573. X    *    11. System-V VLZApeUI
  574. X    *    12. v F l R}hL\& `TLO
  575. X    *    13. lzhuf.c )g  @mK6pMT+\5=B(Fv$)
  576. X
  577. XG L V0.02:
  578. X    1.  verbose/quiet/text_mode option M\> "E7B
  579. X    2.  G    [bZ[W*sKXH* i)`5j\9qB
  580. X    *    3.  
  581. X        1qH`qE""LE5e$)B(^_^)
  582. X    *    4.  TufB Ng
  583. X        A[JCut@C IG    ALbhpFhL<-1F*E+\5=B
  584. X    5.  3k/W
  585. X         >Fv"\7B
  586. X    6.   ;
  587. X        5D"\9qB
  588. X    7.  MS-DOS E V1.13c LA[JCut@C * [MS-DOS] EH-A
  589. X        [generic] IHh\7*AMS-DOS ELLE =h(\*))gM
  590. X        [MS-DOS] FF/E+itH[}bgIHAD"iFv"\7B(^_^)
  591. X    8.  MS-DOS E V1.13c ELTufB Ng
  592. X        W
  593. X    9.  {M vax 11/785 UNIX 4.2BSD E
  594. X        (`FbNRj* i)`5j\9q)
  595. X    *    10.  d66)Fv"\7*AMS-DOS <--> UNIX 
  596. X        L]MoCi
  597. X
  598. XG L V0.01:
  599. X    1.  verbose/quiet/text_mode option M\> "E7B
  600. X    2.  G    [bZ[W*sKXH* i)`5j\9qB
  601. X    3.  
  602. X    4.  TufB Ng
  603. X    5.  3k/W
  604. X         >Fv"\7B
  605. X    6.   ;
  606. X        5D"\9qB
  607. X    7.  MS-DOS E V1.13c LA[JCut@C * [MS-DOS] EH-A
  608. X        [generic] IHh\7*AMS-DOS ELLE =h(\*))gM
  609. X        [MS-DOS] FF/E+itH[}bgIHAD"iFv"\7B(^_^)
  610. X    8.  MS-DOS E V1.13c ELTufB Ng
  611. X        W
  612. X    9.  {M vax 11/785 UNIX 4.2BSD E
  613. X        (`FbNRj* i)`5j\9q)
  614. X
  615. X
  616. X------------------------------------------------------------------------------
  617. SHAR_EOF
  618. chmod 0666 lharc.doc || echo "restore of lharc.doc fails"
  619. echo "x - extracting lhdir.c (Text)"
  620. sed 's/^X//' << 'SHAR_EOF' > lhdir.c &&
  621. X/*----------------------------------------------------------------------*/
  622. X/*        Directory access routine for LHarc UNIX            */
  623. X/*                                    */
  624. X/*        Copyright(C) MCMLXXXIX  Yooichi.Tagawa            */
  625. X/*                                    */
  626. X/*    Emulate opendir(),readdir(),closedir() function for LHarc    */
  627. X/*                                    */
  628. X/*  V0.00  Original                1988.05.31  Y.Tagawa    */
  629. X/*  V0.03  Release #3 for LHarc UNIX        1988.07.02  Y.Tagawa    */
  630. X/*----------------------------------------------------------------------*/
  631. X
  632. X
  633. X#include <sys/types.h>
  634. X
  635. X/* Where is O_RDONLY ? (^_^) */
  636. X#include <sys/file.h>
  637. X#ifndef O_RDONLY
  638. X#include <fcntl.h>
  639. X#endif
  640. X
  641. X#define direct old_direct
  642. X#include <sys/dir.h>
  643. X#undef direct
  644. X
  645. X#include "lhdir.h"
  646. X
  647. XDIR *opendir (name)
  648. X     char *name;
  649. X{
  650. X  register DIR *dirp;
  651. X  register int fd;
  652. X  if ((fd = open (name, O_RDONLY)) >= 0)
  653. X    {
  654. X      if ((dirp = (DIR*)malloc (sizeof (DIR))) != (DIR*)0)
  655. X    {
  656. X      dirp->dd_fd = fd;
  657. X      dirp->dd_loc = 0;
  658. X      dirp->dd_size = 0;
  659. X      return dirp;
  660. X    }
  661. X
  662. X      close (fd);
  663. X    }
  664. X
  665. X  return (DIR*)0;
  666. X}
  667. X
  668. Xstruct direct *readdir (dirp)
  669. X     register DIR *dirp;
  670. X{
  671. X  static struct direct lhdir;
  672. X  register struct old_direct *dp;
  673. X
  674. X  do {
  675. X    if (dirp->dd_loc >= dirp->dd_size)
  676. X      {
  677. X    dirp->dd_loc = 0;
  678. X    if ((dirp->dd_size = read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
  679. X      return (struct direct *)0;
  680. X      }
  681. X
  682. X    dp = (struct old_direct *)(dirp->dd_buf + dirp->dd_loc);
  683. X
  684. X    if (dirp->dd_loc + sizeof (struct old_direct) > dirp->dd_size)
  685. X      return (struct direct *)0;
  686. X
  687. X    dirp->dd_loc += sizeof (struct old_direct);
  688. X
  689. X  } while (dp->d_ino == 0) ;
  690. X
  691. X  /* construct new format */
  692. X  lhdir.d_ino = dp->d_ino;
  693. X  strncpy (lhdir.d_name, dp->d_name, DIRSIZ);
  694. X  lhdir.d_name[DIRSIZ] = '\0';
  695. X  lhdir.d_namlen = strlen (lhdir.d_name);
  696. X
  697. X  return &lhdir;
  698. X}
  699. X
  700. Xclosedir (dirp)
  701. X     DIR *dirp;
  702. X{
  703. X  close (dirp->dd_fd);
  704. X  free (dirp);
  705. X}
  706. X
  707. SHAR_EOF
  708. chmod 0600 lhdir.c || echo "restore of lhdir.c fails"
  709. echo "x - extracting lhdir.h (Text)"
  710. sed 's/^X//' << 'SHAR_EOF' > lhdir.h &&
  711. X/*----------------------------------------------------------------------*/
  712. X/*        Directory access routine for LHarc UNIX            */
  713. X/*                                    */
  714. X/*        Copyright(C) MCMLXXXIX  Yooichi.Tagawa            */
  715. X/*    Emulate opendir(),readdir(),closedir() function for LHarc    */
  716. X/*                                    */
  717. X/*  V0.00  Original                1988.05.31  Y.Tagawa    */
  718. X/*  V0.03  Release #3 for LHarc UNIX        1988.07.02  Y.Tagawa    */
  719. X/*----------------------------------------------------------------------*/
  720. X
  721. X
  722. X/* DIRBLKSIZ must be sizeof (SYSTEM struct direct) * N   !!! */
  723. X
  724. X#ifndef DIRBLKSIZ
  725. X#define DIRBLKSIZ    512
  726. X#endif
  727. X
  728. Xstruct direct {
  729. X  int    d_ino;
  730. X  int    d_namlen;
  731. X  char    d_name[256];
  732. X};
  733. X
  734. Xtypedef struct {
  735. X  int    dd_fd;
  736. X  int    dd_loc;
  737. X  int    dd_size;
  738. X  char    dd_buf[DIRBLKSIZ];
  739. X} DIR;
  740. X
  741. X
  742. Xextern DIR *opendir ();
  743. Xextern struct direct *readdir ();
  744. Xextern closedir ();
  745. X
  746. SHAR_EOF
  747. chmod 0600 lhdir.h || echo "restore of lhdir.h fails"
  748. echo "x - extracting lhio.c (Text)"
  749. sed 's/^X//' << 'SHAR_EOF' > lhio.c &&
  750. X/*----------------------------------------------------------------------*/
  751. X/*        File I/O module for LHarc UNIX                */
  752. X/*                                    */
  753. X/*        Copyright(C) MCMLXXXIX  Yooichi.Tagawa            */
  754. X/*                                    */
  755. X/*  V0.00  Original                1989.06.25  Y.Tagawa    */
  756. X/*  V0.03  Release #3  Beta Version        1989.07.02  Y.Tagawa    */
  757. X/*  V0.03a Fix few bugs                1989.07.04  Y.Tagawa    */
  758. X/*----------------------------------------------------------------------*/
  759. X
  760. X#include <stdio.h>
  761. X#include "lhio.h"
  762. X
  763. X#ifndef BUFFER_SIZE
  764. X#define BUFFER_SIZE    16384
  765. X#endif
  766. X
  767. X
  768. Xextern int    text_mode;            /* in lharc.c */
  769. XFILE            *crc_infile, *crc_outfile;      /* in lzhuf.c */
  770. X
  771. Xextern int rson[];
  772. X
  773. X/* These functions are NO-RETURN */
  774. Xextern read_error ();
  775. Xextern write_error ();
  776. X
  777. X
  778. Xint        crc_getc_cashe;
  779. Xunsigned int    crc_value;
  780. Xunsigned int    crc_table[0x100];
  781. Xlong        crc_size;
  782. X
  783. X
  784. Xcrcsub (ptr, length)
  785. X     char        *ptr;
  786. X     register int    length;
  787. X{
  788. X  register unsigned char    *p;
  789. X  register unsigned int        ctmp;
  790. X
  791. X  if (length != 0)
  792. X    {
  793. X      ctmp = crc_value;
  794. X      p = (unsigned char*)ptr;
  795. X      for (; length; length --)
  796. X    {
  797. X      ctmp ^= (unsigned int)*p++;
  798. X      ctmp = (ctmp >> 8) ^ crc_table [ ctmp & 0xff ];
  799. X    }
  800. X      crc_value = ctmp;
  801. X    }
  802. X}
  803. X
  804. X#ifndef __GNUC__
  805. Xvoid putc_crc (c)
  806. X     int c;
  807. X{
  808. X  CRC_CHAR (c);
  809. X  if (!text_mode || (c != 0x0d && c != 0x1a))
  810. X    {
  811. X      putc (c, crc_outfile);
  812. X    }
  813. X}
  814. X
  815. Xint getc_crc ()
  816. X{
  817. X  int    c;
  818. X
  819. X  if (crc_getc_cashe != EOF)
  820. X    {
  821. X      c = crc_getc_cashe;
  822. X      crc_getc_cashe = EOF;
  823. X      CRC_CHAR (c);
  824. X      crc_size++;
  825. X    }
  826. X  else if ((c = getc (crc_infile)) != EOF)
  827. X    {
  828. X      if (text_mode && c == 0x0a)
  829. X    {
  830. X      crc_getc_cashe = c;
  831. X      c = 0x0d;
  832. X    }
  833. X      CRC_CHAR (c);
  834. X      crc_size++;
  835. X    }
  836. X  return c;
  837. X}
  838. X#endif
  839. X
  840. X
  841. X
  842. Xinit_crc ()
  843. X{
  844. X  static int        inited = 0;
  845. X  register unsigned int    *p = crc_table;
  846. X  register int        i, j;
  847. X  register unsigned int    x;
  848. X
  849. X  if (!inited) {
  850. X    for (j = 0; j < 256; j ++) {
  851. X      x = j;
  852. X      for (i = 0; i < 8; i ++) {
  853. X    if ((x & 1) != 0) {
  854. X      x = (x >> 1) ^ 0xa001;
  855. X    } else {
  856. X      x = (x >> 1);
  857. X    }
  858. X      }
  859. X      *p ++ = x;
  860. X    }
  861. X    inited = 1;
  862. X  }
  863. X  crc_value = 0;
  864. X  crc_getc_cashe = EOF;
  865. X  crc_size = 0;
  866. X}
  867. X
  868. X/*----------------------------------------------------------------------*/
  869. X/*                                    */
  870. X/*----------------------------------------------------------------------*/
  871. X
  872. X/* if return value is -1, see errno */
  873. Xcopy_binary_file (ifp, ofp, size, crc_flag)
  874. X     FILE    *ifp, *ofp;
  875. X     long    size;
  876. X     int    crc_flag;    /* as boolean value */
  877. X{
  878. X  char *buffer = (char *) rson;
  879. X  int read_size;
  880. X  int n;
  881. X
  882. X  /* safty */
  883. X  fflush (ofp);
  884. X
  885. X  while (size > 0)
  886. X    {
  887. X      read_size = ((size < (long)BUFFER_SIZE) ? (int)size : BUFFER_SIZE);
  888. X
  889. X      n = fread (buffer, sizeof (char), read_size, ifp);
  890. X
  891. X      if (n == 0)
  892. X    read_error ();
  893. X
  894. X      if (fwrite (buffer, sizeof (char), n, ofp) < n)
  895. X    write_error ();
  896. X
  897. X      if (crc_flag)
  898. X    crcsub (buffer, n);
  899. X
  900. X      size -= (long)n;
  901. X    }
  902. X}
  903. X
  904. X/* read UNIX text file '0A' and write generic text file '0D0A' */
  905. Xwrite_generic_text_file (ifp, ofp, size)
  906. X     FILE    *ifp, *ofp;
  907. X     long    size;
  908. X{
  909. X  char        buffer[BUFFER_SIZE];
  910. X  int        read_size, write_count, n, m;
  911. X  register char    *p, *p1, *e;
  912. X
  913. X  /* safty */
  914. X  fflush (ofp);
  915. X
  916. X  write_count = 0;
  917. X
  918. X  while (size > 0)
  919. X    {
  920. X      read_size = ((size < BUFFER_SIZE) ? (int)size : BUFFER_SIZE);
  921. X
  922. X      n = fread (buffer, sizeof (char), read_size, ifp);
  923. X
  924. X      if (n == 0)
  925. X    read_error ();
  926. X
  927. X      for (p1 = p = buffer, e = buffer + n; p < e; p++)
  928. X    {
  929. X      if (*p == '\n')
  930. X        {
  931. X          if ((m = p - p1) != 0)
  932. X        {
  933. X          if (fwrite (p1, sizeof (char), m, ofp) < m)
  934. X            write_error ();
  935. X          crcsub (p1, m);
  936. X        }
  937. X          putc (0x0d, ofp);
  938. X          if (feof (ofp))
  939. X        write_error ();
  940. X          CRC_CHAR (0x0d);
  941. X          p1 = p;
  942. X          write_count ++;
  943. X        }
  944. X    }
  945. X      if ((m = p - p1) != 0)
  946. X    {
  947. X      if (fwrite (p1, sizeof (char), m, ofp) < m)
  948. X        write_error ();
  949. X      crcsub (p1, m);
  950. X    }
  951. X
  952. X      write_count += (long)n;
  953. X      size -= (long)n;
  954. X    }
  955. X
  956. X  crc_size = write_count;
  957. X}
  958. X
  959. X/* read generic text file '0D0A' and write UNIX text file '0A' */
  960. Xread_generic_text_file (ifp, ofp, size, crc_flag)
  961. X     FILE    *ifp, *ofp;
  962. X     long    size;
  963. X     int    crc_flag;
  964. X{
  965. X  char        buffer[BUFFER_SIZE];
  966. X  int        read_size, write_size, n, m;
  967. X  register char *p, *p1, *e;
  968. X
  969. X  /* safty */
  970. X  fflush (ofp);
  971. X
  972. X  while (size > 0)
  973. X    {
  974. X      read_size = ((size < BUFFER_SIZE) ? (int)size : BUFFER_SIZE);
  975. X
  976. X      n = fread (buffer, sizeof (char), read_size, ifp);
  977. X
  978. X      if (n == 0)
  979. X    read_error ();
  980. X
  981. X      crcsub (buffer, n);
  982. X
  983. X      for (p1 = p = buffer, e = buffer + n; p < e; p ++)
  984. X    {
  985. X      if (*p == 0x0d)
  986. X        {
  987. X          if ((m = p - p1) != 0)
  988. X        {
  989. X          if (fwrite (p1, sizeof (char), m, ofp) < m)
  990. X            write_error ();
  991. X        }
  992. X          p1 = p+1;
  993. X        }
  994. X    }
  995. X      if ((m = p - p1) != 0)
  996. X    {
  997. X      if (fwrite (p1, sizeof (char), m, ofp) < m)
  998. X        write_error ();
  999. X    }
  1000. X
  1001. X      size -= (long)n;
  1002. X    }
  1003. X}
  1004. X
  1005. X
  1006. X/*----------------------------------------------------------------------*/
  1007. X/*                                    */
  1008. X/*----------------------------------------------------------------------*/
  1009. X
  1010. X
  1011. Xcopy_file (ifp, ofp, size)
  1012. X     FILE    *ifp, *ofp;
  1013. X     long    size;
  1014. X{
  1015. X  copy_binary_file (ifp, ofp, size, 0);
  1016. X}
  1017. X
  1018. X/*ARGSUSED*/
  1019. Xint decode_stored_crc (ifp, ofp, original_size, name)
  1020. X     FILE    *ifp, *ofp;
  1021. X     long    original_size;
  1022. X     char    *name;
  1023. X{
  1024. X  init_crc ();
  1025. X
  1026. X  if (text_mode)
  1027. X    {
  1028. X      read_generic_text_file (ifp, ofp, original_size, 1);
  1029. X      return crc_value;
  1030. X    }
  1031. X  else
  1032. X    {
  1033. X      copy_binary_file (ifp, ofp, original_size, 1);
  1034. X      return crc_value;
  1035. X    }
  1036. X}
  1037. X
  1038. X/*ARGSUSED*/
  1039. Xint decode_stored_nocrc (ifp, ofp, original_size, name)
  1040. X     FILE    *ifp, *ofp;
  1041. X     long    original_size;
  1042. X     char    *name;
  1043. X{
  1044. X  if (text_mode)
  1045. X    {
  1046. X      read_generic_text_file (ifp, ofp, original_size, 0);
  1047. X      return 0;            /* DUMMY */
  1048. X    }
  1049. X  else
  1050. X    {
  1051. X      copy_binary_file (ifp, ofp, original_size, 0);
  1052. X    }
  1053. X  return 0;            /* DUMMY */
  1054. X}
  1055. X
  1056. Xint encode_stored_crc (ifp, ofp, size, original_size_var, write_size_var)
  1057. X     FILE       *ifp, *ofp;
  1058. X     long       size;
  1059. X     long    *original_size_var;
  1060. X     long    *write_size_var;
  1061. X{
  1062. X  init_crc ();
  1063. X
  1064. X  if (text_mode)
  1065. X    {
  1066. X      write_generic_text_file (ifp, ofp, size);
  1067. X      *original_size_var = *write_size_var = crc_size;
  1068. X      return crc_value;
  1069. X    }
  1070. X  else
  1071. X    {
  1072. X      copy_binary_file (ifp, ofp, size, 1);
  1073. X      *original_size_var = size;
  1074. X      *write_size_var = size;
  1075. X      return crc_value;
  1076. X    }
  1077. X}
  1078. SHAR_EOF
  1079. chmod 0666 lhio.c || echo "restore of lhio.c fails"
  1080. echo "x - extracting lhio.h (Text)"
  1081. sed 's/^X//' << 'SHAR_EOF' > lhio.h &&
  1082. X/*----------------------------------------------------------------------*/
  1083. X/*        File I/O module for LHarc UNIX                */
  1084. X/*                                    */
  1085. X/*        Copyright(C) MCMLXXXIX  Yooichi.Tagawa            */
  1086. X/*                                    */
  1087. X/*  V0.00  Original                1989.06.25  Y.Tagawa    */
  1088. X/*  V0.03  Release #3  Beta Version        1989.07.02  Y.Tagawa    */
  1089. X/*----------------------------------------------------------------------*/
  1090. X
  1091. Xextern int        text_mode;
  1092. X
  1093. Xextern unsigned int    crc_table[0x100];
  1094. Xextern unsigned int    crc_value;
  1095. Xextern int        crc_getc_cashe;
  1096. Xextern FILE        *crc_infile, *crc_outfile;
  1097. Xextern long        crc_size;
  1098. X
  1099. X
  1100. X#define CRC_CHAR(c)                        \
  1101. X{ register unsigned int ctmp = crc_value ^ c;             \
  1102. X    crc_value = (ctmp >> 8) ^ crc_table [ ctmp & 0xff ]; }
  1103. X
  1104. X
  1105. X
  1106. X#if defined (__GNUC__)
  1107. X/*#define inlnie*/
  1108. X
  1109. X/* DECODING */
  1110. X/* '0D0A' -> '0A' conversion and strip '1A' when text_mode */
  1111. Xstatic inline putc_crc (int c)
  1112. X{
  1113. X  CRC_CHAR (c);
  1114. X  if (!text_mode || (c != 0x0d && c != 0x1a))
  1115. X    {
  1116. X      putc (c, crc_outfile);
  1117. X    }
  1118. X}
  1119. X
  1120. X/* ENCODING */
  1121. X/* '0A' -> '0D0A' conversion when text_mode */
  1122. Xstatic inline int getc_crc ()
  1123. X{
  1124. X  int    c;
  1125. X
  1126. X  if (crc_getc_cashe != EOF)
  1127. X    {
  1128. X      c = crc_getc_cashe;
  1129. X      crc_getc_cashe = EOF;
  1130. X      CRC_CHAR (c);
  1131. X      crc_size++;
  1132. X    }
  1133. X  else if ((c = getc (crc_infile)) != EOF)
  1134. X    {
  1135. X      if (text_mode && c == 0x0a)
  1136. X    {
  1137. X      crc_getc_cashe = c;
  1138. X      c = 0x0d;
  1139. X    }
  1140. X      CRC_CHAR (c);
  1141. X      crc_size++;
  1142. X    }
  1143. X  return c;
  1144. X}
  1145. X#endif
  1146. SHAR_EOF
  1147. chmod 0666 lhio.h || echo "restore of lhio.h fails"
  1148. echo "x - extracting lzhuf.c (Text)"
  1149. sed 's/^X//' << 'SHAR_EOF' > lzhuf.c &&
  1150. X/*----------------------------------------------------------------------*/
  1151. X/*        lzhuf.c : Encoding/Decoding module for LHarc        */
  1152. X/*                                    */
  1153. X/*    LZSS Algorithm            Haruhiko.Okumura        */
  1154. X/*    Adaptic Huffman Encoding    1989.05.27  Haruyasu.Yoshizaki    */
  1155. X/*                                    */
  1156. X/*                                    */
  1157. X/*    Modified for UNIX LHarc V0.01    1989.05.28  Y.Tagawa        */
  1158. X/*    Modified for UNIX LHarc V0.02    1989.05.29  Y.Tagawa        */
  1159. X/*    Modified for UNIX LHarc V0.03    1989.07.02  Y.Tagawa        */
  1160. X/*----------------------------------------------------------------------*/
  1161. X
  1162. X/* Use ANSI sequences for using only one line per file but
  1163. X * indicator dots on next line */
  1164. X/* #define ANSI */
  1165. X
  1166. X#ifndef ANSI
  1167. X#define DOT       '.'
  1168. X#define BALL      'o'
  1169. X#else
  1170. X#define DOT       249
  1171. X#define BALL      3
  1172. X#define CURSORUP  "\033[A"
  1173. X#define ERASEEOL  "\033[K"
  1174. X#endif
  1175. X
  1176. X#include <stdio.h>
  1177. X
  1178. X#ifndef SELFMAIN
  1179. X#include "lhio.h"
  1180. X#else
  1181. X#define EXIT_SUCCESS    0
  1182. X#define EXIT_FAILURE    1
  1183. X#endif
  1184. X
  1185. X
  1186. X
  1187. XFILE *infile, *outfile;
  1188. Xlong textsize, codesize;
  1189. X
  1190. X
  1191. X#define INDICATOR_THRESHOLD    4096L
  1192. X#define MAX_INDICATOR_COUNT     78
  1193. Xlong indicator_count;
  1194. Xlong indicator_threshold;
  1195. X
  1196. X#ifdef SELFMAIN
  1197. Xint quiet = 0;
  1198. X#else
  1199. Xextern int quiet;
  1200. Xextern int output_to_test;
  1201. X#endif
  1202. X
  1203. X
  1204. X#ifdef SELFMAIN
  1205. X#define SETUP_PUTC_CRC(fp)    /* nothing */
  1206. X#define SETUP_GETC_CRC(fp)    /* nothing */
  1207. X#define PUTC_CRC(c)        putc((c),(outfile))
  1208. X#define GETC_CRC()        getc(infile)
  1209. X#define END_PUTC_CRC()
  1210. X#define END_GETC_CRC()
  1211. X#else
  1212. X#define SETUP_PUTC_CRC(fp)    crc_outfile = fp
  1213. X#define SETUP_GETC_CRC(fp)    crc_infile = fp
  1214. X#define PUTC_CRC(c)        putc_crc(c)
  1215. X#define GETC_CRC()        getc_crc()
  1216. X#define END_PUTC_CRC()
  1217. X#define END_GETC_CRC()
  1218. X#endif
  1219. X
  1220. X
  1221. X
  1222. X
  1223. X#ifdef SELFMAIN
  1224. Xvoid Error (message)
  1225. X    char *message;
  1226. X{
  1227. X    printf("\n%s\n", message);
  1228. X    exit(EXIT_FAILURE);
  1229. X}
  1230. X#endif
  1231. X
  1232. X/*----------------------------------------------------------------------*/
  1233. X/*                                    */
  1234. X/*        LZSS ENCODING                        */
  1235. X/*                                    */
  1236. X/*----------------------------------------------------------------------*/
  1237. X
  1238. X#define N        4096    /* buffer size */
  1239. X#define F        60    /* pre-sence buffer size */
  1240. X#define THRESHOLD    2
  1241. X#define NIL        N    /* term of tree */
  1242. X
  1243. Xunsigned char    text_buf[N + F - 1];
  1244. Xunsigned int     match_position, match_length;
  1245. Xint              lson[N + 1], rson[N + 1 + N], dad[N + 1];
  1246. Xunsigned char    same[N + 1];
  1247. X
  1248. X
  1249. X/* Initialize Tree */
  1250. XInitTree ()
  1251. X{
  1252. X    register int *p, *e;
  1253. X
  1254. X    for (p = rson + N + 1, e = rson + N + N; p <= e; )
  1255. X        *p++ = NIL;
  1256. X    for (p = dad, e = dad + N; p < e; )
  1257. X        *p++ = NIL;
  1258. X}
  1259. X
  1260. X
  1261. X/* Insert to node */
  1262. XInsertNode (r)
  1263. X    register int r;
  1264. X{
  1265. X    register int        p;
  1266. X    int            cmp;
  1267. X    register unsigned char    *key;
  1268. X    register unsigned int    c;
  1269. X    register unsigned int    i, j;
  1270. X
  1271. X    cmp = 1;
  1272. X    key = &text_buf[r];
  1273. X    i = key[1] ^ key[2];
  1274. X    i ^= i >> 4;
  1275. X    p = N + 1 + key[0] + ((i & 0x0f) << 8);
  1276. X    rson[r] = lson[r] = NIL;
  1277. X    match_length = 0;
  1278. X    i = j = 1;
  1279. X    for ( ; ; ) {
  1280. X        if (cmp >= 0) {
  1281. X            if (rson[p] != NIL) {
  1282. X                p = rson[p];
  1283. X                j = same[p];
  1284. X            } else {
  1285. X                rson[p] = r;
  1286. X                dad[r] = p;
  1287. X                same[r] = i;
  1288. X                return;
  1289. X            }
  1290. X        } else {
  1291. X            if (lson[p] != NIL) {
  1292. X                p = lson[p];
  1293. X                j = same[p];
  1294. X            } else {
  1295. X                lson[p] = r;
  1296. X                dad[r] = p;
  1297. X                same[r] = i;
  1298. X                return;
  1299. X            }
  1300. X        }
  1301. X
  1302. X        if (i > j) {
  1303. X            i = j;
  1304. X            cmp = key[i] - text_buf[p + i];
  1305. X        } else
  1306. X        if (i == j) {
  1307. X            for (; i < F; i++)
  1308. X                if ((cmp = key[i] - text_buf[p + i]) != 0)
  1309. X                    break;
  1310. X        }
  1311. X
  1312. X        if (i > THRESHOLD) {
  1313. X            if (i > match_length) {
  1314. X                match_position = ((r - p) & (N - 1)) - 1;
  1315. X                if ((match_length = i) >= F)
  1316. X                    break;
  1317. X            } else
  1318. X            if (i == match_length) {
  1319. X                if ((c = ((r - p) & (N - 1)) - 1) < match_position) {
  1320. X                    match_position = c;
  1321. X                }
  1322. X            }
  1323. X        }
  1324. X    }
  1325. X    same[r] = same[p];
  1326. X    dad[r] = dad[p];
  1327. X    lson[r] = lson[p];
  1328. X    rson[r] = rson[p];
  1329. X    dad[lson[p]] = r;
  1330. X    dad[rson[p]] = r;
  1331. X    if (rson[dad[p]] == p)
  1332. X        rson[dad[p]] = r;
  1333. X    else
  1334. X        lson[dad[p]] = r;
  1335. X    dad[p] = NIL;  /* remove p */
  1336. X}
  1337. X
  1338. X
  1339. Xlink (n, p, q)
  1340. X    int n, p, q;
  1341. X{
  1342. X    register unsigned char *s1, *s2, *s3;
  1343. X    if (p >= NIL) {
  1344. X        same[q] = 1;
  1345. X        return;
  1346. X    }
  1347. X    s1 = text_buf + p + n;
  1348. X    s2 = text_buf + q + n;
  1349. X    s3 = text_buf + p + F;
  1350. X    while (s1 < s3) {
  1351. X        if (*s1++ != *s2++) {
  1352. X            same[q] = s1 - 1 - text_buf - p;
  1353. X            return;
  1354. X        }
  1355. X    }
  1356. X    same[q] = F;
  1357. X}
  1358. X
  1359. X
  1360. Xlinknode (p, q, r)
  1361. X    int p, q, r;
  1362. X{
  1363. X    int cmp;
  1364. X
  1365. X    if ((cmp = same[q] - same[r]) == 0) {
  1366. X        link(same[q], p, r);
  1367. X    } else if (cmp < 0) {
  1368. X        same[r] = same[q];
  1369. X    }
  1370. X}
  1371. X
  1372. XDeleteNode (p)
  1373. X    register int p;
  1374. X{
  1375. X    register int  q;
  1376. X
  1377. X    if (dad[p] == NIL)
  1378. X        return;            /* has no linked */
  1379. X    if (rson[p] == NIL) {
  1380. X        if ((q = lson[p]) != NIL)
  1381. X            linknode(dad[p], p, q);
  1382. X    } else
  1383. X    if (lson[p] == NIL) {
  1384. X        q = rson[p];
  1385. X        linknode(dad[p], p, q);
  1386. X    } else {
  1387. X        q = lson[p];
  1388. X        if (rson[q] != NIL) {
  1389. X            do {
  1390. X                q = rson[q];
  1391. X            } while (rson[q] != NIL);
  1392. X            if (lson[q] != NIL)
  1393. X                linknode(dad[q], q, lson[q]);
  1394. X            link(1, q, lson[p]);
  1395. X            rson[dad[q]] = lson[q];
  1396. X            dad[lson[q]] = dad[q];
  1397. X            lson[q] = lson[p];
  1398. X            dad[lson[p]] = q;
  1399. X        }
  1400. X        link(1, dad[p], q);
  1401. X        link(1, q, rson[p]);
  1402. X        rson[q] = rson[p];
  1403. X        dad[rson[p]] = q;
  1404. X    }
  1405. X    dad[q] = dad[p];
  1406. X    if (rson[dad[p]] == p)
  1407. X        rson[dad[p]] = q;
  1408. X    else
  1409. X        lson[dad[p]] = q;
  1410. X    dad[p] = NIL;
  1411. X}
  1412. X
  1413. X/*----------------------------------------------------------------------*/
  1414. X/*                                    */
  1415. X/*        HUFFMAN ENCODING                    */
  1416. X/*                                    */
  1417. X/*----------------------------------------------------------------------*/
  1418. X
  1419. X#define N_CHAR      (256 - THRESHOLD + F) /* {code : 0 .. N_CHAR-1} */
  1420. X#define T         (N_CHAR * 2 - 1)    /* size of table */
  1421. X#define R         (T - 1)            /* root position */
  1422. X#define MAX_FREQ    0x8000    /* tree update timing from frequency */
  1423. X
  1424. Xtypedef unsigned char uchar;
  1425. X
  1426. X
  1427. X
  1428. X/* TABLE OF ENCODE/DECODE for upper 6bits position information */
  1429. X
  1430. X/* for encode */
  1431. Xuchar p_len[64] = {
  1432. X    0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
  1433. X    0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
  1434. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  1435. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  1436. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  1437. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  1438. X    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  1439. X    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
  1440. X};
  1441. X
  1442. Xuchar p_code[64] = {
  1443. X    0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68,
  1444. X    0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C,
  1445. X    0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
  1446. X    0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
  1447. X    0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
  1448. X    0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
  1449. X    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
  1450. X    0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
  1451. X};
  1452. X
  1453. X/* for decode */
  1454. Xuchar d_code[256] = {
  1455. X    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1456. X    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1457. X    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1458. X    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1459. X    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  1460. X    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  1461. X    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  1462. X    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  1463. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  1464. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  1465. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  1466. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  1467. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  1468. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  1469. X    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  1470. X    0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
  1471. X    0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
  1472. X    0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
  1473. X    0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
  1474. X    0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
  1475. X    0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
  1476. X    0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
  1477. X    0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
  1478. X    0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
  1479. X    0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
  1480. X    0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
  1481. X    0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
  1482. X    0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
  1483. X    0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
  1484. X    0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
  1485. X    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  1486. X    0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  1487. X};
  1488. X
  1489. Xuchar d_len[256] = {
  1490. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  1491. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  1492. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  1493. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  1494. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  1495. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  1496. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  1497. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  1498. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  1499. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  1500. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  1501. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  1502. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  1503. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  1504. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  1505. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  1506. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  1507. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  1508. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  1509. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  1510. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  1511. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  1512. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  1513. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  1514. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  1515. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  1516. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  1517. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  1518. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  1519. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  1520. X    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  1521. X    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  1522. X};
  1523. X
  1524. Xunsigned freq[T + 1];    /* frequency table */
  1525. X
  1526. Xint prnt[T + N_CHAR];    /* points to parent node */
  1527. X/* notes :
  1528. X   prnt[T .. T + N_CHAR - 1] used by
  1529. X   indicates leaf position that corresponding to code */
  1530. X
  1531. Xint son[T];              /* points to son node (son[i],son[i+]) */
  1532. X
  1533. Xunsigned getbuf = 0;
  1534. Xuchar getlen = 0;
  1535. X
  1536. X
  1537. X/* get one bit */
  1538. X/* returning in Bit 0 */
  1539. Xint GetBit ()
  1540. X{
  1541. X    register unsigned int dx = getbuf;
  1542. X    register unsigned int c;
  1543. X
  1544. X    if (getlen <= 8)
  1545. X        {
  1546. X            c = getc (infile);
  1547. X            if ((int)c < 0) c = 0;
  1548. X            dx |= c << (8 - getlen);
  1549. X            getlen += 8;
  1550. X        }
  1551. X    getbuf = dx << 1;
  1552. X    getlen--;
  1553. X    return (dx & 0x8000) ? 1 : 0;
  1554. X}
  1555. X
  1556. X/* get one byte */
  1557. X/* returning in Bit7...0 */
  1558. Xint GetByte ()
  1559. X{
  1560. X    register unsigned int dx = getbuf;
  1561. X    register unsigned c;
  1562. X
  1563. X    if (getlen <= 8) {
  1564. X        c = getc (infile);
  1565. X        if ((int)c < 0) c = 0;
  1566. X        dx |= c << (8 - getlen);
  1567. X        getlen += 8;
  1568. X    }
  1569. X    getbuf = dx << 8;
  1570. X    getlen -= 8;
  1571. X    return (dx >> 8) & 0xff;
  1572. X}
  1573. X
  1574. X/* get N bit */
  1575. X/* returning in Bit(N-1)...Bit 0 */
  1576. Xint GetNBits (n)
  1577. X    register unsigned int n;
  1578. X{
  1579. X    register unsigned int dx = getbuf;
  1580. X    register unsigned int c;
  1581. X    static int mask[17] = {
  1582. X        0x0000,
  1583. X        0x0001, 0x0003, 0x0007, 0x000f,
  1584. X        0x001f, 0x003f, 0x007f, 0x00ff,
  1585. X        0x01ff, 0x03ff, 0x07ff, 0x0fff,
  1586. X        0x1fff, 0x3fff, 0x0fff, 0xffff };
  1587. X    static int shift[17] = {
  1588. X        16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
  1589. X
  1590. X    if (getlen <= 8)
  1591. X        {
  1592. X            c = getc (infile);
  1593. X            if ((int)c < 0) c = 0;
  1594. X            dx |= c << (8 - getlen);
  1595. X            getlen += 8;
  1596. X        }
  1597. X    getbuf = dx << n;
  1598. X    getlen -= n;
  1599. X    return (dx >> shift[n]) & mask[n];
  1600. X}
  1601. X
  1602. Xunsigned putbuf = 0;
  1603. Xuchar putlen = 0;
  1604. X
  1605. X/* output C bits */
  1606. XPutcode (l, c)
  1607. X    register int l;
  1608. X    register unsigned int c;
  1609. X{
  1610. X    register len = putlen;
  1611. X    register unsigned int b = putbuf;
  1612. X    b |= c >> len;
  1613. X    if ((len += l) >= 8) {
  1614. X        putc (b >> 8, outfile);
  1615. X        if ((len -= 8) >= 8) {
  1616. X            putc (b, outfile);
  1617. X            codesize += 2;
  1618. X            len -= 8;
  1619. X            b = c << (l - len);
  1620. X        } else {
  1621. X            b <<= 8;
  1622. X            codesize++;
  1623. X        }
  1624. X    }
  1625. X    putbuf = b;
  1626. X    putlen = len;
  1627. X}
  1628. X
  1629. X
  1630. X/* Initialize tree */
  1631. X
  1632. XStartHuff ()
  1633. X{
  1634. X    register int i, j;
  1635. X
  1636. X    for (i = 0; i < N_CHAR; i++) {
  1637. X        freq[i] = 1;
  1638. X        son[i] = i + T;
  1639. X        prnt[i + T] = i;
  1640. X    }
  1641. X    i = 0; j = N_CHAR;
  1642. X    while (j <= R) {
  1643. X        freq[j] = freq[i] + freq[i + 1];
  1644. X        son[j] = i;
  1645. X        prnt[i] = prnt[i + 1] = j;
  1646. X        i += 2; j++;
  1647. X    }
  1648. X    freq[T] = 0xffff;
  1649. X    prnt[R] = 0;
  1650. X    putlen = getlen = 0;
  1651. X    putbuf = getbuf = 0;
  1652. X}
  1653. X
  1654. X
  1655. X/* reconstruct tree */
  1656. Xreconst ()
  1657. X{
  1658. X    register int i, j, k;
  1659. X    register unsigned f;
  1660. X
  1661. X    /* correct leaf node into of first half,
  1662. X       and set these freqency to (freq+1)/2       */
  1663. X    j = 0;
  1664. X    for (i = 0; i < T; i++) {
  1665. X        if (son[i] >= T) {
  1666. X            freq[j] = (freq[i] + 1) / 2;
  1667. X            son[j] = son[i];
  1668. X            j++;
  1669. X        }
  1670. X    }
  1671. X    /* build tree.  Link sons first */
  1672. X    for (i = 0, j = N_CHAR; j < T; i += 2, j++) {
  1673. X        k = i + 1;
  1674. X        f = freq[j] = freq[i] + freq[k];
  1675. X        for (k = j - 1; f < freq[k]; k--);
  1676. X        k++;
  1677. X        {    register unsigned *p, *e;
  1678. X            for (p = &freq[j], e = &freq[k]; p > e; p--)
  1679. X                p[0] = p[-1];
  1680. X            freq[k] = f;
  1681. X        }
  1682. X        {    register int *p, *e;
  1683. X            for (p = &son[j], e = &son[k]; p > e; p--)
  1684. X                p[0] = p[-1];
  1685. X            son[k] = i;
  1686. X        }
  1687. X    }
  1688. X    /* link parents */
  1689. X    for (i = 0; i < T; i++) {
  1690. X        if ((k = son[i]) >= T) {
  1691. X            prnt[k] = i;
  1692. X        } else {
  1693. X            prnt[k] = prnt[k + 1] = i;
  1694. X        }
  1695. X    }
  1696. X}
  1697. X
  1698. X
  1699. X/* update given code's frequency, and update tree */
  1700. X
  1701. Xupdate (c)
  1702. X    unsigned int    c;
  1703. X{
  1704. X    register unsigned *p;
  1705. X    register int i, j, k, l;
  1706. X
  1707. X    if (freq[R] == MAX_FREQ) {
  1708. X        reconst();
  1709. X    }
  1710. X    c = prnt[c + T];
  1711. X    do {
  1712. X        k = ++freq[c];
  1713. X
  1714. X        /* swap nodes when become wrong frequency order. */
  1715. X        if (k > freq[l = c + 1]) {
  1716. X            for (p = freq+l+1; k > *p++; ) ;
  1717. X            l = p - freq - 2;
  1718. X            freq[c] = p[-2];
  1719. X            p[-2] = k;
  1720. X
  1721. X            i = son[c];
  1722. X            prnt[i] = l;
  1723. X            if (i < T) prnt[i + 1] = l;
  1724. X
  1725. X            j = son[l];
  1726. X            son[l] = i;
  1727. X
  1728. X            prnt[j] = c;
  1729. X            if (j < T) prnt[j + 1] = c;
  1730. X            son[c] = j;
  1731. X
  1732. X            c = l;
  1733. X        }
  1734. X    } while ((c = prnt[c]) != 0);    /* loop until reach to root */
  1735. X}
  1736. X
  1737. X/* unsigned code, len; */
  1738. X
  1739. XEncodeChar (c)
  1740. X    unsigned c;
  1741. X{
  1742. X    register int *p;
  1743. X    register unsigned long i;
  1744. X    register int j, k;
  1745. X
  1746. X    i = 0;
  1747. X    j = 0;
  1748. X    p = prnt;
  1749. X    k = p[c + T];
  1750. X
  1751. X    /* trace links from leaf node to root */
  1752. X    do {
  1753. X        i >>= 1;
  1754. X
  1755. X        /* if node index is odd, trace larger of sons */
  1756. X        if (k & 1) i += 0x80000000;
  1757. X
  1758. X        j++;
  1759. X    } while ((k = p[k]) != R) ;
  1760. X    if (j > 16) {
  1761. X        Putcode(16, (unsigned int)(i >> 16));
  1762. X        Putcode(j - 16, (unsigned int)i);
  1763. X    } else {
  1764. X        Putcode(j, (unsigned int)(i >> 16));
  1765. X    }
  1766. X/*    code = i; */
  1767. X/*     len = j; */
  1768. X    update(c);
  1769. X}
  1770. X
  1771. XEncodePosition (c)
  1772. X    unsigned c;
  1773. X{
  1774. X    unsigned i;
  1775. X
  1776. X    /* output upper 6bit from table */
  1777. X    i = c >> 6;
  1778. X    Putcode((int)(p_len[i]), (unsigned int)(p_code[i]) << 8);
  1779. X
  1780. X    /* output lower 6 bit */
  1781. X    Putcode(6, (unsigned int)(c & 0x3f) << 10);
  1782. X}
  1783. X
  1784. XEncodeEnd ()
  1785. X{
  1786. X    if (putlen) {
  1787. X        putc(putbuf >> 8, outfile);
  1788. X        codesize++;
  1789. X    }
  1790. X}
  1791. X
  1792. Xint DecodeChar ()
  1793. X{
  1794. X    register unsigned c;
  1795. X
  1796. X    c = son[R];
  1797. X
  1798. X    /* trace from root to leaf,
  1799. X       got bit is 0 to small(son[]), 1 to large (son[]+1) son node */
  1800. X    while (c < T) {
  1801. X        c += GetBit();
  1802. X        c = son[c];
  1803. X    }
  1804. X    c -= T;
  1805. X    update(c);
  1806. X    return c;
  1807. X}
  1808. X
  1809. Xint DecodePosition ()
  1810. X{
  1811. X    unsigned i, j, c;
  1812. X
  1813. X    /* decode upper 6bit from table */
  1814. X    i = GetByte();
  1815. X    c = (unsigned)d_code[i] << 6;
  1816. X    j = d_len[i];
  1817. X
  1818. X    /* get lower 6bit */
  1819. X    j -= 2;
  1820. X    return c | (((i << j) | GetNBits (j)) & 0x3f);
  1821. X}
  1822. X
  1823. X
  1824. XEncode ()
  1825. X{
  1826. X    register int  i, c, len, r, s, last_match_length;
  1827. X
  1828. X    if (textsize == 0)
  1829. X        return;
  1830. X
  1831. X    textsize = 0;
  1832. X    StartHuff();
  1833. X    InitTree();
  1834. X    s = 0;
  1835. X    r = N - F;
  1836. X    for (i = s; i < r; i++)
  1837. X        text_buf[i] = ' ';
  1838. X    for (len = 0; len < F && (c = GETC_CRC()) != EOF; len++)
  1839. X        text_buf[r + len] = c;
  1840. X    textsize = len;
  1841. X    for (i = 1; i <= F; i++)
  1842. X        InsertNode(r - i);
  1843. X    InsertNode(r);
  1844. X    do {
  1845. X        if (match_length > len)
  1846. X            match_length = len;
  1847. X        if (match_length <= THRESHOLD) {
  1848. X            match_length = 1;
  1849. X            EncodeChar(text_buf[r]);
  1850. X        } else {
  1851. X            EncodeChar(255 - THRESHOLD + match_length);
  1852. X            EncodePosition(match_position);
  1853. X        }
  1854. X        last_match_length = match_length;
  1855. X        for (i = 0; i < last_match_length &&
  1856. X                (c = GETC_CRC()) != EOF; i++) {
  1857. X            DeleteNode(s);
  1858. X            text_buf[s] = c;
  1859. X            if (s < F - 1)
  1860. X                text_buf[s + N] = c;
  1861. X            s = (s + 1) & (N - 1);
  1862. X            r = (r + 1) & (N - 1);
  1863. X            InsertNode(r);
  1864. X        }
  1865. X
  1866. X        textsize += i;
  1867. X        if ((textsize > indicator_count) && !quiet) {
  1868. X            putchar (BALL);
  1869. X            fflush (stdout);
  1870. X            indicator_count += indicator_threshold;
  1871. X        }
  1872. X        while (i++ < last_match_length) {
  1873. X            DeleteNode(s);
  1874. X            s = (s + 1) & (N - 1);
  1875. X            r = (r + 1) & (N - 1);
  1876. X            if (--len) InsertNode(r);
  1877. X        }
  1878. X    } while (len > 0);
  1879. X    EncodeEnd();
  1880. X    END_GETC_CRC ();
  1881. X}
  1882. X
  1883. XDecode ()
  1884. X{
  1885. X    register int    i, j, k, r, c;
  1886. X    register long    count;
  1887. X
  1888. X#ifdef SELFMAIN
  1889. X    if (textsize == 0)
  1890. X        return;
  1891. X#endif
  1892. X    StartHuff();
  1893. X    for (i = 0; i < N - F; i++)
  1894. X        text_buf[i] = ' ';
  1895. X    r = N - F;
  1896. X    for (count = 0; count < textsize; ) {
  1897. X        c = DecodeChar();
  1898. X        if (c < 256) {
  1899. X            PUTC_CRC (c);
  1900. X            text_buf[r++] = c;
  1901. X            r &= (N - 1);
  1902. X            count++;
  1903. X        } else {
  1904. X            i = (r - DecodePosition() - 1) & (N - 1);
  1905. X            j = c - 255 + THRESHOLD;
  1906. X            for (k = 0; k < j; k++) {
  1907. X                c = text_buf[(i + k) & (N - 1)];
  1908. X                PUTC_CRC (c);
  1909. X                text_buf[r++] = c;
  1910. X                r &= (N - 1);
  1911. X                count++;
  1912. X            }
  1913. X        }
  1914. X
  1915. X        if (!quiet && (count > indicator_count)) {
  1916. X            putchar (BALL);
  1917. X            fflush (stdout);
  1918. X            indicator_count += indicator_threshold;
  1919. X        }
  1920. X    }
  1921. X    END_PUTC_CRC ();
  1922. X}
  1923. X
  1924. X
  1925. X/*----------------------------------------------------------------------*/
  1926. X/*                                    */
  1927. X/*        LARC                            */
  1928. X/*                                    */
  1929. X/*----------------------------------------------------------------------*/
  1930. X
  1931. X#define F_OLD    18    /* look ahead buffer size for LArc */
  1932. X
  1933. X/* intialize buffer for LArc type 5 */
  1934. XInitBuf ()
  1935. X{
  1936. X    register unsigned char *p = text_buf;
  1937. X    register int i, j;
  1938. X    for (i = 0; i < 256; i ++)
  1939. X        for (j = 0; j < 13; j ++)
  1940. X            *p ++ = i;
  1941. X    for (i = 0; i < 256; i ++)
  1942. X        *p ++ = i;
  1943. X    for (i = 0; i < 256; i ++)
  1944. X        *p ++ = 255 - i;
  1945. X    for (i = 0; i < 128; i ++)
  1946. X        *p ++ = 0;
  1947. X    for (i = 0; i < 128; i ++)
  1948. X        *p ++ = 0x20;
  1949. X}
  1950. X
  1951. X/* Decode LArc type 5 */
  1952. XDecodeOld ()
  1953. X{
  1954. X    register int si, di;
  1955. X    register long count;
  1956. X    int    dl, dh, al, cx;
  1957. X    if (textsize == 0)
  1958. X        return;
  1959. X
  1960. X    InitBuf ();
  1961. X    di = N - F_OLD;
  1962. X    dl = 0x80;
  1963. X
  1964. X    for (count = 0; count < textsize; ) {
  1965. X        dl = ((dl << 1) | (dl >> 7)) & 0xff;
  1966. X        if (dl & 0x01)
  1967. X            dh = getc (infile);
  1968. X        al = getc (infile);
  1969. X        if ((dh & dl) != 0) {
  1970. X            PUTC_CRC (al);
  1971. X            text_buf[di] = al;
  1972. X            di = (di + 1) & (N - 1);
  1973. X            count ++;
  1974. X        } else {
  1975. X            cx = getc (infile);
  1976. X            si = (al & 0x00ff) | ((cx << 4) & 0x0f00);
  1977. X            cx = (cx & 0x000f) + 3;
  1978. X            count += cx;
  1979. X            do {
  1980. X                text_buf[di] = al = text_buf[si];
  1981. X                PUTC_CRC (al);
  1982. X                si = (si + 1) & (N - 1);
  1983. X                di = (di + 1) & (N - 1);
  1984. X            } while (--cx != 0) ;
  1985. X        }
  1986. X
  1987. X        if (!quiet && (count > indicator_count)) {
  1988. X            putchar (BALL);
  1989. X            fflush (stdout);
  1990. X            indicator_count += indicator_threshold;
  1991. X        }
  1992. X    }
  1993. X    END_PUTC_CRC ();
  1994. X}
  1995. X
  1996. X
  1997. X
  1998. X/*----------------------------------------------------------------------*/
  1999. X/*                                    */
  2000. X/*        Global Entries for Archiver Driver            */
  2001. X/*                                    */
  2002. X/*----------------------------------------------------------------------*/
  2003. X
  2004. X
  2005. Xstart_indicator (name, size, msg)
  2006. X    char *name;
  2007. X    long size;
  2008. X    char *msg;
  2009. X{
  2010. X    long    i;
  2011. X    int    m;
  2012. X
  2013. X    if (quiet)
  2014. X        return;
  2015. X
  2016. X#ifdef ANSI
  2017. X    m = MAX_INDICATOR_COUNT;
  2018. X#else
  2019. X    m = MAX_INDICATOR_COUNT - strlen (name);
  2020. X#endif
  2021. X    if (m < 0)
  2022. X        m = 3;        /* (^_^) */
  2023. X
  2024. X#ifdef ANSI
  2025. X        printf ("\r%s - %s:\n", name, msg);
  2026. X#else
  2027. X        printf ("\r%s - %s :  ", name, msg);
  2028. X#endif
  2029. X
  2030. X    indicator_threshold =
  2031. X        ((size  + (m * INDICATOR_THRESHOLD - 1)) /
  2032. X         (m * INDICATOR_THRESHOLD) *
  2033. X         INDICATOR_THRESHOLD);
  2034. X
  2035. X    /* bug fix for files with size==0 28.03.1990 SB */
  2036. X    if (indicator_threshold == 0)
  2037. X        indicator_threshold = INDICATOR_THRESHOLD;
  2038. X    /************************************************/
  2039. X
  2040. X    i = ((size + (indicator_threshold - 1)) / indicator_threshold);
  2041. X    while (i--)
  2042. X        putchar (DOT);
  2043. X    indicator_count = 0;
  2044. X#ifdef ANSI
  2045. X        printf ("\r%s%s - %s:\n", CURSORUP, name, msg);
  2046. X#else
  2047. X        printf ("\r%s - %s :  ", name, msg);
  2048. X#endif
  2049. X    fflush (stdout);
  2050. X}
  2051. X
  2052. Xfinish_indicator2 (name, msg, pcnt)
  2053. X    char *name;
  2054. X    char *msg;
  2055. X    int pcnt;
  2056. X{
  2057. X    if (quiet)
  2058. X        return;
  2059. X
  2060. X    if (pcnt > 100) pcnt = 100;    /* (^_^) */
  2061. X#ifdef ANSI
  2062. X        printf ("\r%s%s - %s(%d%%)\n%s", CURSORUP, name, msg, pcnt, ERASEEOL);
  2063. X#else
  2064. X        printf ("\r%s - %s(%d%%)\n", name, msg, pcnt);
  2065. X#endif
  2066. X    fflush (stdout);
  2067. X}
  2068. X
  2069. Xfinish_indicator (name, msg)
  2070. X    char *name;
  2071. X    char *msg;
  2072. X{
  2073. X    if (quiet)
  2074. X        return;
  2075. X
  2076. X#ifdef ANSI
  2077. X        printf ("\r%s%s - %s\n%s", CURSORUP, name, msg, ERASEEOL);
  2078. X#else
  2079. X        printf ("\r%s - %s\n", name, msg);
  2080. X#endif
  2081. X    fflush (stdout);
  2082. X}
  2083. X
  2084. X
  2085. X#ifndef SELFMAIN
  2086. Xint encode_lzhuf (infp, outfp, size, original_size_var, packed_size_var, name)
  2087. X    FILE *infp;
  2088. X    FILE *outfp;
  2089. X    long size;
  2090. X    long *original_size_var;
  2091. X    long *packed_size_var;
  2092. X    char *name;
  2093. X{
  2094. X    infile = infp;
  2095. X    outfile = outfp;
  2096. X    SETUP_GETC_CRC(infp);
  2097. X    textsize = size;
  2098. X    codesize = 0;
  2099. X    init_crc ();
  2100. X    start_indicator (name, size, "Freezing");
  2101. X    Encode ();
  2102. X    finish_indicator2 (name, "Frozen",
  2103. X               (int)((codesize * 100L) / crc_size));
  2104. X    *packed_size_var = codesize;
  2105. X    *original_size_var = crc_size;
  2106. X    return crc_value;
  2107. X}
  2108. X
  2109. Xint decode_lzhuf (infp, outfp, original_size, name)
  2110. X    FILE *infp;
  2111. X    FILE *outfp;
  2112. X    long original_size;
  2113. X    char *name;
  2114. X{
  2115. X    infile = infp;
  2116. X    outfile = outfp;
  2117. X    SETUP_PUTC_CRC(outfp);
  2118. X    textsize = original_size;
  2119. X    init_crc ();
  2120. X        start_indicator (name, original_size,
  2121. X                         (output_to_test ? "Testing" : "Melting"));
  2122. X    Decode ();
  2123. X        finish_indicator (name, (output_to_test ? "Tested  " : "Melted  "));
  2124. X    return crc_value;
  2125. X}
  2126. X
  2127. X
  2128. Xint decode_larc (infp, outfp, original_size, name)
  2129. X    FILE *infp, *outfp;
  2130. X    long original_size;
  2131. X    char *name;
  2132. X{
  2133. X    infile = infp;
  2134. X    outfile = outfp;
  2135. X    SETUP_PUTC_CRC(outfp);
  2136. X    textsize = original_size;
  2137. X    init_crc ();
  2138. X        start_indicator (name, original_size,
  2139. X                         (output_to_test ? "Testing" : "Melting"));
  2140. X    DecodeOld ();
  2141. X        finish_indicator (name, (output_to_test ? "Tested  " : "Melted  "));
  2142. X    return crc_value;
  2143. X}
  2144. X#endif
  2145. X
  2146. X#ifdef SELFMAIN
  2147. Xint main (argc, argv)
  2148. X    int argc;
  2149. X    char *argv[];
  2150. X{
  2151. X    char  *s;
  2152. X    int i;
  2153. X
  2154. X    indicator_count = 0;
  2155. X    indicator_threshold = 1024;
  2156. X    textsize = codesize = 0;
  2157. X    if (argc != 4) {
  2158. X        printf ("\
  2159. Xusage: lzhuf e in_file out_file (packing)\n\
  2160. X       lzhuf d in_file out_file (unpacking)\n");
  2161. X        return EXIT_FAILURE;
  2162. X    }
  2163. X    if ((s = argv[1], ((*s != 'e') && (*s != 'd')) || s[1] != '\0') ||
  2164. X        (s = argv[2], (infile  = fopen(s, "rb")) == NULL) ||
  2165. X        (s = argv[3], (outfile = fopen(s, "wb")) == NULL)) {
  2166. X        printf("??? %s\n", s);
  2167. X        return EXIT_FAILURE;
  2168. X    }
  2169. X    if (argv[1][0] == 'e') {
  2170. X        /* Get original text size and output it */
  2171. X        fseek(infile, 0L, 2);
  2172. X        textsize = ftell(infile);
  2173. X        rewind (infile);
  2174. X        if (fwrite(&textsize, sizeof textsize, 1, outfile) < 1)
  2175. X            Error("cannot write");
  2176. X
  2177. X        start_indicator (argv[2], textsize, "Freezing");
  2178. X        Encode();
  2179. X        finith_indicator2 (argv[2], "Frozen",
  2180. X                   (int)((codesize * 100L) / textsize));
  2181. X
  2182. X        printf("input : %ld bytes\n", textsize);
  2183. X        printf("output: %ld bytes\n", codesize);
  2184. X    } else {
  2185. X        /* Read original text size */
  2186. X        if (fread(&textsize, sizeof textsize, 1, infile) < 1)
  2187. X            Error("cannot read");
  2188. X
  2189. X        start_indicator (argv[2], textsize, "Melting");
  2190. X        Decode();
  2191. X        finish_indicator (argv[2], "Melted  ");
  2192. X    }
  2193. X    fclose(infile);
  2194. X    fclose(outfile);
  2195. X    return EXIT_SUCCESS;
  2196. X}
  2197. X#endif
  2198. X
  2199. X
  2200. X/* These lines are used in GNU-Emacs */
  2201. X/* Local Variables: */
  2202. X/* comment-column:40 */
  2203. X/* tab-width:8 */
  2204. X/* c-indent-level:8 */
  2205. X/* c-continued-statement-offset:8 */
  2206. X/* c-argdecl-indent:8 */
  2207. X/* End: */
  2208. SHAR_EOF
  2209. chmod 0666 lzhuf.c || echo "restore of lzhuf.c fails"
  2210. echo "x - extracting mktemp.c (Text)"
  2211. sed 's/^X//' << 'SHAR_EOF' > mktemp.c &&
  2212. X/* MKTEMP.C using TMP environment variable */
  2213. X
  2214. X#include <stdio.h>
  2215. X#include <stdlib.h>
  2216. X#include <string.h>
  2217. X#include <io.h>
  2218. X
  2219. Xvoid Mktemp(char *file)
  2220. X{
  2221. X  char fname[32], *tmp;
  2222. X
  2223. X  tmp = getenv("TMP");
  2224. X
  2225. X  if ( tmp != NULL )
  2226. X  {
  2227. X    strcpy(fname, file);
  2228. X    strcpy(file, tmp);
  2229. X
  2230. X    if ( file[strlen(file) - 1] != '\\' )
  2231. X      strcat(file, "\\");
  2232. X
  2233. X    strcat(file, fname);
  2234. X  }
  2235. X
  2236. X  mktemp(file);
  2237. X}
  2238. X
  2239. X/* End of MKTEMP.C */
  2240. SHAR_EOF
  2241. chmod 0666 mktemp.c || echo "restore of mktemp.c fails"
  2242. echo "x - extracting pipes.c (Text)"
  2243. sed 's/^X//' << 'SHAR_EOF' > pipes.c &&
  2244. X/* a simulation for the Unix popen() and pclose() calls on MS-DOS */
  2245. X/* only one pipe can be open at a time */
  2246. X
  2247. X#include <stdio.h>
  2248. X#include <stdlib.h>
  2249. X#include <string.h>
  2250. X
  2251. Xstatic char pipename[128], command[128];
  2252. Xstatic int wrpipe;
  2253. X
  2254. Xextern void Mktemp(char *);
  2255. X
  2256. XFILE *popen(char *cmd, char *flags)
  2257. X{
  2258. X  wrpipe = (strchr(flags, 'w') != NULL);
  2259. X
  2260. X  if ( wrpipe )
  2261. X  {
  2262. X    strcpy(command, cmd);
  2263. X    strcpy(pipename, "~WXXXXXX");
  2264. X    Mktemp(pipename);
  2265. X    return fopen(pipename, flags);  /* ordinary file */
  2266. X  }
  2267. X  else
  2268. X  {
  2269. X    strcpy(pipename, "~RXXXXXX");
  2270. X    Mktemp(pipename);
  2271. X    strcpy(command, cmd);
  2272. X    strcat(command, ">");
  2273. X    strcat(command, pipename);
  2274. X    system(command);
  2275. X    return fopen(pipename, flags);  /* ordinary file */
  2276. X  }
  2277. X}
  2278. X
  2279. Xint pclose(FILE *pipe)
  2280. X{
  2281. X  int rc;
  2282. X
  2283. X  if ( fclose(pipe) == EOF )
  2284. X    return EOF;
  2285. X
  2286. X  if ( wrpipe )
  2287. X  {
  2288. X    if ( command[strlen(command) - 1] == '!' )
  2289. X      command[strlen(command) - 1] = 0;
  2290. X    else
  2291. X      strcat(command, "<");
  2292. X
  2293. X    strcat(command, pipename);
  2294. X    rc = system(command);
  2295. X    unlink(pipename);
  2296. X    return rc;
  2297. X  }
  2298. X  else
  2299. X  {
  2300. X    unlink(pipename);
  2301. X    return 0;
  2302. X  }
  2303. X}
  2304. SHAR_EOF
  2305. chmod 0666 pipes.c || echo "restore of pipes.c fails"
  2306. rm -f s2_seq_.tmp
  2307. echo "You have unpacked the last part"
  2308. exit 0
  2309.  
  2310. -- 
  2311. bill davidsen    (davidsen@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen)
  2312.     VMS is a text-only adventure game. If you win you can use unix.
  2313.