home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume11 / lharc / part02 < prev    next >
Encoding:
Text File  |  1990-03-10  |  52.1 KB  |  2,300 lines

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