hdecode.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /*
  24. * COMPONENT_NAME: austext
  25. *
  26. * FUNCTIONS: hc_decode
  27. * main
  28. *
  29. * ORIGINS: 27
  30. *
  31. *
  32. * (C) COPYRIGHT International Business Machines Corp. 1990,1995
  33. * All Rights Reserved
  34. * Licensed Materials - Property of IBM
  35. * US Government Users Restricted Rights - Use, duplication or
  36. * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  37. */
  38. /************************* HDECODE.C ***************************
  39. * $XConsortium: hdecode.c /main/8 1996/11/21 19:50:15 drk $
  40. * 1990.
  41. * Decode function that reads in a Huffman Code bitstring and returns the
  42. * original plaintext characters. Intended use of Huffman Code is
  43. * both compression and encryption of text lines in Opera System.
  44. * Decode (decryption) is optimized for high speed, online use.
  45. *
  46. * Global Arguments:
  47. * 'hctree' is decode table in form of array of integers.
  48. * Each integer pair forms a node in a huffman code tree.
  49. * See huffcode.c for full discussion of its organization.
  50. * If 'hctree' is NULL, the tree has not been linked into
  51. * current object module, and this function must read the
  52. * source file and create the tree at execution time.
  53. * This flexibility allows internal use of decode function
  54. * using different trees without having to recompile/relink.
  55. * The linked-in version is more secure for external customer use.
  56. * 'hctree_name' is filename prefix for both encode (.huf) and
  57. * encode (.c) source files. If 'hctree' is NULL, this is
  58. * the file from which the tree will be built.
  59. * 'hctree_id' is unique unix timestamp indicating when hctree was
  60. * create. It is compared with caller's (encoder's) passed stamp
  61. * to ensure encode/decode compatibility.
  62. * 'hctree_root' is the integer index of the root node in hctree.
  63. * By luck, this is always the LAST node so it also gives an
  64. * indication of the storage needed when the tree has to be
  65. * allocated at execution time.
  66. *
  67. * Passed Arguments:
  68. * 'bitstring' is the address of the huffman encoded cyphertext.
  69. * It begins on byte boundary, but may end in middle of
  70. * a byte depending on charcount.
  71. * 'charbuf' is the output buffer where the plaintext characters
  72. * will be assembled.
  73. * 'charcount' is the number of plaintext bytes that were encoded into
  74. * the passed bitstring, and will be assembled into charbuf.
  75. *
  76. * $Log$
  77. * Revision 2.3 1996/03/13 22:56:26 miker
  78. * Changed char to UCHAR several places.
  79. *
  80. * Revision 2.2 1995/10/25 17:51:46 miker
  81. * Added prolog.
  82. *
  83. * Revision 2.1 1995/09/22 20:50:00 miker
  84. * Freeze DtSearch 0.1, AusText 2.1.8
  85. *
  86. * Revision 1.3 1995/09/05 18:02:21 miker
  87. * Name changes for DtSearch.
  88. */
  89. #include "SearchP.h"
  90. #include <errno.h>
  91. #define X_INCLUDE_STRING_H
  92. #define XOS_USE_NO_LOCKING
  93. #include <X11/Xos_r.h>
  94. #define HDEC_FBUFSZ 128
  95. #define PROGNAME "HDECODE"
  96. #define MS_huff 30 /* message catalog set number */
  97. extern char *hctree_name;
  98. extern time_t hctree_id;
  99. extern int hctree_root;
  100. extern int *hctree;
  101. /*---------------- TREENODE structure ---------------------*/
  102. typedef struct {
  103. int branch0;
  104. int branch1;
  105. } TREENODE;
  106. /************************************************/
  107. /* */
  108. /* HC Decode */
  109. /* */
  110. /************************************************/
  111. void hc_decode (
  112. UCHAR *bitstring, /* input: compressed data */
  113. UCHAR *charbuf, /* output: uncompressed data */
  114. int charcount, /* input: length uncompressed data */
  115. time_t encode_id)
  116. { /* input: compression table to use */
  117. #ifdef DEBUG_DECODE
  118. static int first_time = TRUE;
  119. #endif
  120. int bitreg;
  121. int i;
  122. int bitcount;
  123. int tree_index;
  124. TREENODE *tree_addr;
  125. #ifdef EXTERNAL_TREE
  126. char *ptr;
  127. char *hdecode_filebuf;
  128. FILE *hdecode_file;
  129. _Xstrtokparams strtok_buf;
  130. #endif
  131. #ifdef EXTERNAL_TREE
  132. /* Create hctree from external file? */
  133. if (hctree == NULL) {
  134. if ((hdecode_filebuf = malloc (HDEC_FBUFSZ)) == NULL) {
  135. fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_huff, 10,
  136. "%s Out of Memory.\n"),
  137. PROGNAME"076");
  138. DtSearchExit (2);
  139. }
  140. if ((hdecode_file = fopen (hctree_name, "r")) == NULL) {
  141. fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_huff, 11,
  142. "%s Cannot open tree file '%s': %s\n"),
  143. PROGNAME"082", hctree_name, strerror (errno));
  144. DtSearchExit (2);
  145. }
  146. /* read first few lines to load global variables */
  147. for (i = 0; i < 3; i++)
  148. fgets (hdecode_filebuf, HDEC_FBUFSZ, hdecode_file);
  149. ptr = strchr (hdecode_filebuf, '=');
  150. hctree_id = atol (ptr + 1);
  151. fgets (hdecode_filebuf, HDEC_FBUFSZ, hdecode_file);
  152. ptr = strchr (hdecode_filebuf, '=');
  153. hctree_root = atoi (ptr + 1);
  154. fgets (hdecode_filebuf, HDEC_FBUFSZ, hdecode_file); /* throwaway */
  155. /* allocate space for the hctree and read in the values */
  156. if ((hctree = (int *) malloc (
  157. sizeof (int) * 2 * (hctree_root + 2))) == NULL) {
  158. fprintf (aa_stderr, "\n" PROGNAME "100 Out of Memory.\7\n");
  159. DtSearchExit (2);
  160. }
  161. for (i = 0; i <= hctree_root; i++) {
  162. if ((fgets (hdecode_filebuf, HDEC_FBUFSZ, hdecode_file)) == NULL) {
  163. fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_huff, 12,
  164. "%s Invalid format hctree '%s'.\n"),
  165. PROGNAME"106", hctree_name);
  166. DtSearchExit (2);
  167. }
  168. hctree[2 * i] = atoi (_XStrtok (hdecode_filebuf, " \t,", strtok_buf));
  169. hctree[2 * i + 1] = atoi (_XStrtok (NULL, " \t,", strtok_buf));
  170. }
  171. free (hdecode_filebuf);
  172. fclose (hdecode_file);
  173. } /* endif where hctree created from external file */
  174. #endif /* for EXTERNAL_TREE */
  175. #ifdef DEBUG_DECODE
  176. if (first_time) {
  177. first_time = FALSE;
  178. printf ("\n***** created hctree from '%s' ******\n"
  179. "hctree_id = %ld\nhctree_root = %d\n",
  180. hctree_name, hctree_id, hctree_root);
  181. }
  182. #endif
  183. if (encode_id != hctree_id) {
  184. fprintf (aa_stderr, CATGETS(dtsearch_catd, MS_huff, 13,
  185. "%s Incompatible hctree_ids.\n"),
  186. PROGNAME"118");
  187. DtSearchExit (2);
  188. }
  189. tree_addr = (TREENODE *) hctree;
  190. bitcount = 0;
  191. while (charcount-- > 0) { /****** MAIN OUTPUT CHARACTER LOOP ******/
  192. tree_index = hctree_root;
  193. while (tree_index >= 0) { /****** TREE TRAVERSAL LOOP ******/
  194. /* retrieve next bit */
  195. if (bitcount <= 0) { /* read next input char? */
  196. bitcount = 8;
  197. bitreg = *bitstring++;
  198. }
  199. bitreg <<= 1;
  200. bitcount--;
  201. if (bitreg & 0x0100)
  202. tree_index = tree_addr[tree_index].branch1;
  203. else
  204. tree_index = tree_addr[tree_index].branch0;
  205. } /* end tree traversal loop */
  206. /******** DECODE CHARACTER ********/
  207. /* if literal code, retrieve next 8 bits as char itself */
  208. if ((tree_index += 257) == 256) {
  209. tree_index = 0;
  210. for (i = 8; i > 0; i--) {
  211. if (bitcount <= 0) { /* read next input char? */
  212. bitcount = 8;
  213. bitreg = *bitstring++;
  214. }
  215. bitreg <<= 1;
  216. bitcount--;
  217. tree_index <<= 1;
  218. if (bitreg & 0x0100)
  219. tree_index |= 1;
  220. } /* end 8-bit for loop */
  221. } /* endif to process literal coding */
  222. *charbuf = tree_index;
  223. charbuf++;
  224. } /* end main output character loop */
  225. return;
  226. } /* end of function hc_decode */
  227. #ifdef DEBUG_DECODE
  228. /************************************************/
  229. /* */
  230. /* Main */
  231. /* */
  232. /************************************************/
  233. void main (int argc, char *argv[])
  234. {
  235. #define BITSTR_BUFSIZE 140
  236. FILE *instream;
  237. FILE *aa_stderr = stderr;
  238. char stringbuf[BITSTR_BUFSIZE + 2];
  239. char charbuf[9 * BITSTR_BUFSIZE];
  240. char fname_tree[80];
  241. int mychar;
  242. int oops;
  243. int i;
  244. union {
  245. INT integer;
  246. char chars[2];
  247. } charcount;
  248. if (argc <= 1) {
  249. puts ("Usage: hdecode [hucfile] cypherfile");
  250. return;
  251. }
  252. if (argc >= 3) {
  253. hctree = NULL;
  254. append_ext (fname_tree, sizeof (fname_tree), argv[1], EXT_HDECODE);
  255. hctree_name = fname_tree;
  256. argv++;
  257. }
  258. if ((instream = fopen (argv[1], "rb")) == NULL) {
  259. fprintf (aa_stderr, "Cannot open cypherfile '%s'.\n", argv[1]);
  260. exit (2);
  261. }
  262. MAINLOOP:
  263. /**************/
  264. if ((mychar = fgetc (instream)) == EOF)
  265. return;
  266. charcount.chars[0] = mychar;
  267. if ((mychar = fgetc (instream)) == EOF)
  268. return;
  269. charcount.chars[1] = mychar;
  270. if (charcount.integer > sizeof (charbuf) - 2) {
  271. oops = TRUE;
  272. charcount.integer = sizeof (charbuf) - 2;
  273. }
  274. else
  275. oops = FALSE;
  276. /* printf("\n\n***** charcount = %d %s*****\n",
  277. charcount.integer, (oops) ? "(reduced)" : "");*/
  278. for (i = 0; i < BITSTR_BUFSIZE; i++) {
  279. if ((mychar = fgetc (instream)) == EOF) {
  280. fprintf (aa_stderr, "\n" PROGNAME "202 Unexpected EOF '%s'.\n",
  281. argv[1]);
  282. exit (2);
  283. }
  284. stringbuf[i] = mychar;
  285. }
  286. hc_decode (stringbuf, charbuf, charcount.integer, hctree_id);
  287. for (i = 0; i < charcount.integer; i++)
  288. putchar (charbuf[i]);
  289. goto MAINLOOP;
  290. /************/
  291. } /* end of function main */
  292. #endif
  293. /************************* HDECODE.C ***************************/