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

Annotation 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 - (hide 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 jmc 1.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