/[MITgcm]/MITgcm_contrib/mpack_src/mpack-1.6-4/macbhex.c
ViewVC logotype

Contents of /MITgcm_contrib/mpack_src/mpack-1.6-4/macbhex.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download)
Sat Feb 23 20:22:58 2008 UTC (17 years, 4 months ago) by jmc
Branch: MAIN
CVS Tags: HEAD
File MIME type: text/plain
- get new version from: http://packages.qa.debian.org/m/mpack.html
  (files: mpack_1.6.orig.tar.gz, mpack_1.6-4.diff.gz, mpack_1.6-4.dsc)
  and apply patch 'mpack_1.6-4.diff' to original dir: mpack_1.6/
- this fix the MD5 coding on 64.bit platforms (well, seems to).
- added in Contrib to allow separate test (since building mpack seems fishy)

1 /* macbhex.c -- simple binhex decoding routine */
2 /* (C) Copyright 1993,1994 by Carnegie Mellon University
3 * All Rights Reserved.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without
7 * fee, provided that the above copyright notice appear in all copies
8 * and that both that copyright notice and this permission notice
9 * appear in supporting documentation, and that the name of Carnegie
10 * Mellon University not be used in advertising or publicity
11 * pertaining to distribution of the software without specific,
12 * written prior permission. Carnegie Mellon University makes no
13 * representations about the suitability of this software for any
14 * purpose. It is provided "as is" without express or implied
15 * warranty.
16 *
17 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
18 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
20 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
22 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
23 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24 * SOFTWARE.
25 */
26
27 #include <stdio.h>
28 #include <ctype.h>
29 #include <memory.h>
30 #include "part.h"
31 #include "macnapp.h"
32 #include "macmpack.h"
33
34 /* from macos.c: */
35 extern void renameDescFile(char *, short, long);
36
37 char binhex_decode[256] = {
38 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
39 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
40 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, -1, -1,
41 13, 14, 15, 16, 17, 18, 19, -1, 20, 21, -1, -1, -1, -1, -1, -1,
42 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, -1,
43 37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46, 47, -1, -1, -1, -1,
44 48, 49, 50, 51, 52, 53, 54, -1, 55, 56, 57, 58, 59, 60, -1, -1,
45 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
46 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
48 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
49 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
50 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
51 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
52 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
53 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
54 };
55 #define BHEXVAL(c) (binhex_decode[(unsigned char) c])
56
57 typedef union {
58 unsigned char c[4];
59 unsigned long val;
60 } longbuf;
61
62 typedef struct {
63 OSType type, creator;
64 unsigned short flags;
65 long dlen, rlen;
66 } binhex_header;
67
68 #define STATE_START 0
69 #define STATE_FNAME 1
70 #define STATE_HEADER 2
71 #define STATE_HCRC 3
72 #define STATE_DFORK 4
73 #define STATE_DCRC 5
74 #define STATE_RFORK 6
75 #define STATE_RCRC 7
76 #define STATE_DONE 8
77 #define STATE_ERROR 9
78
79 typedef struct binhex_state {
80 short state; /* current state */
81 short part; /* current part number */
82 unsigned short CRC; /* cumulative CRC */
83 unsigned short fileCRC; /* CRC value from file */
84 longbuf octetbuf; /* buffer for decoded 6-bit values */
85 short octetin; /* current input position in octetbuf */
86 short donepos; /* ending position in octetbuf */
87 short inCRC; /* flag set when reading a CRC */
88 long count; /* generic counter */
89 FILE *outfile; /* output file */
90 short marker; /* flag indicating maker */
91 unsigned char rlebuf; /* buffer for last run length encoding value */
92 PCstr namebuf[65]; /* buffer for binhex filename */
93 binhex_header head; /* buffer for header */
94 FSSpec fspec; /* output file */
95 } binhex_state;
96
97 /* global state */
98 static binhex_state bh;
99
100 /* process a binhex character
101 */
102 static void binhex_process(struct part *inpart)
103 {
104 unsigned short tmpcrc, cval;
105 unsigned char ctmp, c = bh.rlebuf;
106 StandardFileReply reply;
107 FInfo finfo;
108 char buf[256];
109
110 /* do CRC */
111 ctmp = bh.inCRC ? c : 0;
112 cval = bh.CRC & 0xf000;
113 tmpcrc = ((unsigned short) (bh.CRC << 4) | (ctmp >> 4))
114 ^ (cval | (cval >> 7) | (cval >> 12));
115 cval = tmpcrc & 0xf000;
116 bh.CRC = ((unsigned short) (tmpcrc << 4) | (ctmp & 0x0f))
117 ^ (cval | (cval >> 7) | (cval >> 12));
118
119 /* handle state */
120 switch (bh.state) {
121 case STATE_START:
122 bh.state = STATE_FNAME;
123 bh.count = 1;
124 *bh.namebuf = (c & 63);
125 break;
126 case STATE_FNAME:
127 bh.namebuf[bh.count] = c;
128 if (bh.count++ > *bh.namebuf) {
129 bh.state = STATE_HEADER;
130 bh.count = 0;
131 }
132 break;
133 case STATE_HEADER:
134 ((char *)&bh.head)[bh.count] = c;
135 if (++bh.count == 18) {
136 bh.state = STATE_HCRC;
137 bh.inCRC = 1;
138 bh.count = 0;
139 }
140 break;
141 case STATE_DFORK:
142 case STATE_RFORK:
143 putc(c, bh.outfile);
144 if (--bh.count == 0) {
145 fclose(bh.outfile);
146 bh.outfile = NULL;
147 ++bh.state;
148 bh.inCRC = 1;
149 }
150 break;
151 case STATE_HCRC:
152 case STATE_DCRC:
153 case STATE_RCRC:
154 if (!bh.count++) {
155 bh.fileCRC = (unsigned short) c << 8;
156 } else {
157 if ((bh.fileCRC | c) != bh.CRC) {
158 if (bh.state > STATE_HCRC) {
159 HDelete(bh.fspec.vRefNum, bh.fspec.parID, bh.fspec.name);
160 SetCursor(&arrow);
161 yell("BinHex file corrupted in transit");
162 SetCursor(&watch);
163 }
164 bh.state = STATE_ERROR;
165 break;
166 }
167 bh.CRC = 0;
168 if (++bh.state == STATE_DONE) {
169 finfo.fdType = bh.head.type;
170 finfo.fdCreator = bh.head.creator;
171 finfo.fdFlags = bh.head.flags & 0xf800;
172 HSetFInfo(bh.fspec.vRefNum, bh.fspec.parID, bh.fspec.name, &finfo);
173 PtoCstr(bh.fspec.name);
174 renameDescFile((char *)bh.fspec.name, bh.fspec.vRefNum, bh.fspec.parID);
175 break;
176 }
177 bh.count = bh.head.rlen;
178 if (bh.state == STATE_DFORK) {
179 /* prompt user */
180 sprintf(buf, "Saving BinHex file %s", C(bh.namebuf));
181 chat(buf);
182 SetCursor(&arrow);
183 NAputFile("\pSave decoded BinHex file as:", P(bh.namebuf), &reply);
184 SetCursor(&watch);
185 statrefresh();
186 if (!reply.sfGood) {
187 didchat = -1;
188 bh.state = STATE_ERROR;
189 } else {
190 bh.fspec = reply.sfFile;
191 HCreate(bh.fspec.vRefNum, bh.fspec.parID, bh.fspec.name,
192 bh.head.creator, bh.head.type);
193 bh.count = bh.head.dlen;
194 }
195 }
196 if (bh.count) {
197 bh.inCRC = 0;
198 bh.outfile = Macopen(inpart->infile, bh.fspec.name, bh.fspec.vRefNum,
199 bh.fspec.parID, 1, bh.state == STATE_DFORK ? 0 : 1, fsWrPerm);
200 if (!bh.outfile) {
201 bh.state = STATE_ERROR;
202 HDelete(bh.fspec.vRefNum, bh.fspec.parID, bh.fspec.name);
203 SetCursor(&arrow);
204 yell("Failed to open file for writing");
205 SetCursor(&watch);
206 }
207 } else {
208 ++bh.state;
209 }
210 }
211 break;
212 }
213 }
214
215 /*
216 * decode a binhex file
217 * returns -1 on fatal error, 0 for continue, 1 for done
218 */
219 int os_binhex(struct part *inpart, int part, int nparts)
220 {
221 long val;
222 int c;
223 char *bptr;
224 short octetpos;
225 static char buf[1024];
226
227 /* reset state */
228 if (part == 1) {
229 bh.state = STATE_START;
230 bh.part = 0;
231 bh.CRC = 0;
232 bh.octetbuf.val = 0;
233 bh.octetin = 26;
234 bh.donepos = 3;
235 bh.inCRC = 0;
236 bh.outfile = NULL;
237 bh.marker = 0;
238 }
239 if (++bh.part != part) bh.state = STATE_ERROR;
240
241 /* do nothing on error/completion */
242 if (!inpart) {
243 if (bh.state < STATE_DONE) bh.state = STATE_ERROR;
244 } else {
245 /* skip blank lines */
246 do {
247 if (part_gets(buf, sizeof (buf), inpart) == NULL) return (0);
248 } while (*buf == '\n');
249 bptr = buf;
250 if (part == 1 && *bptr++ != ':') bh.state = STATE_ERROR;
251
252 /* line reading loop */
253 do {
254 /* check line for separator */
255 if (!strncmp(buf, "--- ", 4)) break;
256 buf[strlen(buf) - 1] = '\0';
257
258 /* loop through line of binhex charaters */
259 while (bh.state < STATE_DONE) {
260 /* fill in octetbuf */
261 do {
262 if ((val = BHEXVAL(*bptr++)) == -1) {
263 if (bptr[-1]) {
264 --bh.donepos;
265 if (bh.octetin >= 14) --bh.donepos;
266 if (bh.octetin >= 20) --bh.donepos;
267 }
268 break;
269 }
270 bh.octetbuf.val |= val << bh.octetin;
271 } while ((bh.octetin -= 6) > 2);
272 if (!bptr[-1]) break;
273
274 /* handle decoded characters -- run length encoding (rle) detection */
275 for (octetpos = 0; octetpos < bh.donepos; ++octetpos) {
276 /* get character & handle rle */
277 c = bh.octetbuf.c[octetpos];
278 if (c == 0x90 && !bh.marker++) continue;
279 if (bh.marker) {
280 if (c == 0) {
281 bh.rlebuf = 0x90;
282 binhex_process(inpart);
283 } else {
284 while (--c > 0) {
285 binhex_process(inpart);
286 }
287 }
288 bh.marker = 0;
289 } else {
290 bh.rlebuf = (unsigned char) c;
291 binhex_process(inpart);
292 }
293 if (bh.state >= STATE_DONE) break;
294 }
295 if (bh.donepos < 3 && bh.state < STATE_DONE) bh.state = STATE_ERROR;
296 bh.octetin = 26;
297 bh.octetbuf.val = 0;
298 }
299 } while (bh.state < STATE_DONE && part_gets(bptr = buf, sizeof (buf), inpart) != NULL);
300 }
301
302 /* error clean up */
303 if (bh.state == STATE_ERROR && bh.outfile) {
304 fclose(bh.outfile);
305 bh.outfile = NULL;
306 HDelete(bh.fspec.vRefNum, bh.fspec.parID, bh.fspec.name);
307 }
308
309 return (bh.state == STATE_ERROR ? 1 : 0);
310 }

  ViewVC Help
Powered by ViewVC 1.1.22