2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)record.c 1.1 00/04/26 joerg */
15 * hfsutils - tools for reading and writing Macintosh HFS volumes
16 * Copyright (C) 1996, 1997 Robert Leslie
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
43 * NAME: record->packcatkey()
44 * DESCRIPTION: pack a catalog record key
46 void r_packcatkey(CatKeyRec *key, unsigned char *pkey, int *len)
48 unsigned char *start = pkey;
50 d_storeb(&pkey, key->ckrKeyLen);
51 d_storeb(&pkey, key->ckrResrv1);
52 d_storel(&pkey, key->ckrParID);
53 d_stores(&pkey, key->ckrCName, sizeof(key->ckrCName));
56 *len = HFS_RECKEYSKIP(start);
60 * NAME: record->unpackcatkey()
61 * DESCRIPTION: unpack a catalog record key
63 void r_unpackcatkey(unsigned char *pkey, CatKeyRec *key)
65 d_fetchb(&pkey, (char *) &key->ckrKeyLen);
66 d_fetchb(&pkey, (char *) &key->ckrResrv1);
67 d_fetchl(&pkey, (long *) &key->ckrParID);
68 d_fetchs(&pkey, key->ckrCName, sizeof(key->ckrCName));
72 * NAME: record->packextkey()
73 * DESCRIPTION: pack an extents record key
75 void r_packextkey(ExtKeyRec *key, unsigned char *pkey, int *len)
77 unsigned char *start = pkey;
79 d_storeb(&pkey, key->xkrKeyLen);
80 d_storeb(&pkey, key->xkrFkType);
81 d_storel(&pkey, key->xkrFNum);
82 d_storew(&pkey, key->xkrFABN);
85 *len = HFS_RECKEYSKIP(start);
89 * NAME: record->unpackextkey()
90 * DESCRIPTION: unpack an extents record key
92 void r_unpackextkey(unsigned char *pkey, ExtKeyRec *key)
94 d_fetchb(&pkey, (char *) &key->xkrKeyLen);
95 d_fetchb(&pkey, (char *) &key->xkrFkType);
96 d_fetchl(&pkey, (long *) &key->xkrFNum);
97 d_fetchw(&pkey, (short *) &key->xkrFABN);
101 * NAME: record->comparecatkeys()
102 * DESCRIPTION: compare two (packed) catalog record keys
104 int r_comparecatkeys(unsigned char *pkey1, unsigned char *pkey2)
110 r_unpackcatkey(pkey1, &key1);
111 r_unpackcatkey(pkey2, &key2);
113 diff = key1.ckrParID - key2.ckrParID;
117 return d_relstring(key1.ckrCName, key2.ckrCName);
121 * NAME: record->compareextkeys()
122 * DESCRIPTION: compare two (packed) extents record keys
124 int r_compareextkeys(unsigned char *pkey1, unsigned char *pkey2)
130 r_unpackextkey(pkey1, &key1);
131 r_unpackextkey(pkey2, &key2);
133 diff = key1.xkrFNum - key2.xkrFNum;
137 diff = (unsigned char) key1.xkrFkType -
138 (unsigned char) key2.xkrFkType;
142 return key1.xkrFABN - key2.xkrFABN;
146 * NAME: record->packcatdata()
147 * DESCRIPTION: pack catalog record data
149 void r_packcatdata(CatDataRec *data, unsigned char *pdata, int *len)
151 unsigned char *start = pdata;
154 d_storeb(&pdata, data->cdrType);
155 d_storeb(&pdata, data->cdrResrv2);
157 switch (data->cdrType)
160 d_storew(&pdata, data->u.dir.dirFlags);
161 d_storew(&pdata, data->u.dir.dirVal);
162 d_storel(&pdata, data->u.dir.dirDirID);
163 d_storel(&pdata, data->u.dir.dirCrDat);
164 d_storel(&pdata, data->u.dir.dirMdDat);
165 d_storel(&pdata, data->u.dir.dirBkDat);
167 d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.top);
168 d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.left);
169 d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.bottom);
170 d_storew(&pdata, data->u.dir.dirUsrInfo.frRect.right);
171 d_storew(&pdata, data->u.dir.dirUsrInfo.frFlags);
172 d_storew(&pdata, data->u.dir.dirUsrInfo.frLocation.v);
173 d_storew(&pdata, data->u.dir.dirUsrInfo.frLocation.h);
174 d_storew(&pdata, data->u.dir.dirUsrInfo.frView);
176 d_storew(&pdata, data->u.dir.dirFndrInfo.frScroll.v);
177 d_storew(&pdata, data->u.dir.dirFndrInfo.frScroll.h);
178 d_storel(&pdata, data->u.dir.dirFndrInfo.frOpenChain);
179 d_storew(&pdata, data->u.dir.dirFndrInfo.frUnused);
180 d_storew(&pdata, data->u.dir.dirFndrInfo.frComment);
181 d_storel(&pdata, data->u.dir.dirFndrInfo.frPutAway);
183 for (i = 0; i < 4; ++i)
184 d_storel(&pdata, data->u.dir.dirResrv[i]);
189 d_storeb(&pdata, data->u.fil.filFlags);
190 d_storeb(&pdata, data->u.fil.filTyp);
192 d_storel(&pdata, data->u.fil.filUsrWds.fdType);
193 d_storel(&pdata, data->u.fil.filUsrWds.fdCreator);
194 d_storew(&pdata, data->u.fil.filUsrWds.fdFlags);
195 d_storew(&pdata, data->u.fil.filUsrWds.fdLocation.v);
196 d_storew(&pdata, data->u.fil.filUsrWds.fdLocation.h);
197 d_storew(&pdata, data->u.fil.filUsrWds.fdFldr);
199 d_storel(&pdata, data->u.fil.filFlNum);
201 d_storew(&pdata, data->u.fil.filStBlk);
202 d_storel(&pdata, data->u.fil.filLgLen);
203 d_storel(&pdata, data->u.fil.filPyLen);
205 d_storew(&pdata, data->u.fil.filRStBlk);
206 d_storel(&pdata, data->u.fil.filRLgLen);
207 d_storel(&pdata, data->u.fil.filRPyLen);
209 d_storel(&pdata, data->u.fil.filCrDat);
210 d_storel(&pdata, data->u.fil.filMdDat);
211 d_storel(&pdata, data->u.fil.filBkDat);
213 d_storew(&pdata, data->u.fil.filFndrInfo.fdIconID);
214 for (i = 0; i < 4; ++i)
215 d_storew(&pdata, data->u.fil.filFndrInfo.fdUnused[i]);
216 d_storew(&pdata, data->u.fil.filFndrInfo.fdComment);
217 d_storel(&pdata, data->u.fil.filFndrInfo.fdPutAway);
219 d_storew(&pdata, data->u.fil.filClpSize);
221 for (i = 0; i < 3; ++i)
223 d_storew(&pdata, data->u.fil.filExtRec[i].xdrStABN);
224 d_storew(&pdata, data->u.fil.filExtRec[i].xdrNumABlks);
227 for (i = 0; i < 3; ++i)
229 d_storew(&pdata, data->u.fil.filRExtRec[i].xdrStABN);
230 d_storew(&pdata, data->u.fil.filRExtRec[i].xdrNumABlks);
233 d_storel(&pdata, data->u.fil.filResrv);
237 for (i = 0; i < 2; ++i)
238 d_storel(&pdata, data->u.dthd.thdResrv[i]);
240 d_storel(&pdata, data->u.dthd.thdParID);
241 d_stores(&pdata, data->u.dthd.thdCName, sizeof(data->u.dthd.thdCName));
245 for (i = 0; i < 2; ++i)
246 d_storel(&pdata, data->u.fthd.fthdResrv[i]);
248 d_storel(&pdata, data->u.fthd.fthdParID);
249 d_stores(&pdata, data->u.fthd.fthdCName, sizeof(data->u.fthd.fthdCName));
257 *len += pdata - start;
261 * NAME: record->unpackcatdata()
262 * DESCRIPTION: unpack catalog record data
264 void r_unpackcatdata(unsigned char *pdata, CatDataRec *data)
268 d_fetchb(&pdata, (char *) &data->cdrType);
269 d_fetchb(&pdata, (char *) &data->cdrResrv2);
271 switch (data->cdrType)
274 d_fetchw(&pdata, &data->u.dir.dirFlags);
275 d_fetchw(&pdata, (short *) &data->u.dir.dirVal);
276 d_fetchl(&pdata, (long *) &data->u.dir.dirDirID);
277 d_fetchl(&pdata, &data->u.dir.dirCrDat);
278 d_fetchl(&pdata, &data->u.dir.dirMdDat);
279 d_fetchl(&pdata, &data->u.dir.dirBkDat);
281 d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.top);
282 d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.left);
283 d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.bottom);
284 d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frRect.right);
285 d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frFlags);
286 d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frLocation.v);
287 d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frLocation.h);
288 d_fetchw(&pdata, &data->u.dir.dirUsrInfo.frView);
290 d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frScroll.v);
291 d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frScroll.h);
292 d_fetchl(&pdata, &data->u.dir.dirFndrInfo.frOpenChain);
293 d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frUnused);
294 d_fetchw(&pdata, &data->u.dir.dirFndrInfo.frComment);
295 d_fetchl(&pdata, &data->u.dir.dirFndrInfo.frPutAway);
297 for (i = 0; i < 4; ++i)
298 d_fetchl(&pdata, &data->u.dir.dirResrv[i]);
303 d_fetchb(&pdata, (char *) &data->u.fil.filFlags);
304 d_fetchb(&pdata, (char *) &data->u.fil.filTyp);
306 d_fetchl(&pdata, &data->u.fil.filUsrWds.fdType);
307 d_fetchl(&pdata, &data->u.fil.filUsrWds.fdCreator);
308 d_fetchw(&pdata, &data->u.fil.filUsrWds.fdFlags);
309 d_fetchw(&pdata, &data->u.fil.filUsrWds.fdLocation.v);
310 d_fetchw(&pdata, &data->u.fil.filUsrWds.fdLocation.h);
311 d_fetchw(&pdata, &data->u.fil.filUsrWds.fdFldr);
313 d_fetchl(&pdata, (long *) &data->u.fil.filFlNum);
315 d_fetchw(&pdata, (short *) &data->u.fil.filStBlk);
316 d_fetchl(&pdata, (long *) &data->u.fil.filLgLen);
317 d_fetchl(&pdata, (long *) &data->u.fil.filPyLen);
319 d_fetchw(&pdata, (short *) &data->u.fil.filRStBlk);
320 d_fetchl(&pdata, (long *) &data->u.fil.filRLgLen);
321 d_fetchl(&pdata, (long *) &data->u.fil.filRPyLen);
323 d_fetchl(&pdata, &data->u.fil.filCrDat);
324 d_fetchl(&pdata, &data->u.fil.filMdDat);
325 d_fetchl(&pdata, &data->u.fil.filBkDat);
327 d_fetchw(&pdata, &data->u.fil.filFndrInfo.fdIconID);
328 for (i = 0; i < 4; ++i)
329 d_fetchw(&pdata, &data->u.fil.filFndrInfo.fdUnused[i]);
330 d_fetchw(&pdata, &data->u.fil.filFndrInfo.fdComment);
331 d_fetchl(&pdata, &data->u.fil.filFndrInfo.fdPutAway);
333 d_fetchw(&pdata, (short *) &data->u.fil.filClpSize);
335 for (i = 0; i < 3; ++i)
337 d_fetchw(&pdata, (short *) &data->u.fil.filExtRec[i].xdrStABN);
338 d_fetchw(&pdata, (short *) &data->u.fil.filExtRec[i].xdrNumABlks);
341 for (i = 0; i < 3; ++i)
343 d_fetchw(&pdata, (short *) &data->u.fil.filRExtRec[i].xdrStABN);
344 d_fetchw(&pdata, (short *) &data->u.fil.filRExtRec[i].xdrNumABlks);
347 d_fetchl(&pdata, &data->u.fil.filResrv);
351 for (i = 0; i < 2; ++i)
352 d_fetchl(&pdata, &data->u.dthd.thdResrv[i]);
354 d_fetchl(&pdata, (long *) &data->u.dthd.thdParID);
355 d_fetchs(&pdata, data->u.dthd.thdCName, sizeof(data->u.dthd.thdCName));
359 for (i = 0; i < 2; ++i)
360 d_fetchl(&pdata, &data->u.fthd.fthdResrv[i]);
362 d_fetchl(&pdata, (long *) &data->u.fthd.fthdParID);
363 d_fetchs(&pdata, data->u.fthd.fthdCName, sizeof(data->u.fthd.fthdCName));
372 * NAME: record->packextdata()
373 * DESCRIPTION: pack extent record data
375 void r_packextdata(ExtDataRec *data, unsigned char *pdata, int *len)
377 unsigned char *start = pdata;
380 for (i = 0; i < 3; ++i)
382 d_storew(&pdata, (*data)[i].xdrStABN);
383 d_storew(&pdata, (*data)[i].xdrNumABlks);
387 *len += pdata - start;
391 * NAME: record->unpackextdata()
392 * DESCRIPTION: unpack extent record data
394 void r_unpackextdata(unsigned char *pdata, ExtDataRec *data)
398 for (i = 0; i < 3; ++i)
400 d_fetchw(&pdata, (short *) &(*data)[i].xdrStABN);
401 d_fetchw(&pdata, (short *) &(*data)[i].xdrNumABlks);
406 * NAME: record->makecatkey()
407 * DESCRIPTION: construct a catalog record key
409 void r_makecatkey(CatKeyRec *key, long parid, char *name)
413 len = strlen(name) + 1;
415 key->ckrKeyLen = 0x05 + len + (len & 1);
417 key->ckrParID = parid;
419 strcpy(key->ckrCName, name);
423 * NAME: record->makeextkey()
424 * DESCRIPTION: construct an extents record key
426 void r_makeextkey(ExtKeyRec *key, int ffork, long fnum, unsigned int fabn)
428 key->xkrKeyLen = 0x07;
429 key->xkrFkType = ffork;
435 * NAME: record->unpackdirent()
436 * DESCRIPTION: unpack catalog information into hfsdirent structure
440 void r_unpackdirent(long parid, char *name, CatDataRec *data, hfsdirent *ent)
442 strcpy(ent->name, name);
445 switch (data->cdrType)
448 ent->flags = HFS_ISDIR;
449 ent->cnid = data->u.dir.dirDirID;
451 ent->crdate = d_toutime(data->u.dir.dirCrDat);
452 ent->mddate = d_toutime(data->u.dir.dirMdDat);
453 ent->bkdate = d_toutime(data->u.dir.dirBkDat);
455 ent->fdflags = data->u.dir.dirUsrInfo.frFlags;
456 ent->fdlocation.v = data->u.dir.dirUsrInfo.frLocation.v;
457 ent->fdlocation.h = data->u.dir.dirUsrInfo.frLocation.h;
459 ent->u.dir.valence = data->u.dir.dirVal;
461 ent->u.dir.rect.top = data->u.dir.dirUsrInfo.frRect.top;
462 ent->u.dir.rect.left = data->u.dir.dirUsrInfo.frRect.left;
463 ent->u.dir.rect.bottom = data->u.dir.dirUsrInfo.frRect.bottom;
464 ent->u.dir.rect.right = data->u.dir.dirUsrInfo.frRect.right;
467 ent->u.dir.frscroll.v = data->u.dir.dirFndrInfo.frScroll.v;
468 ent->u.dir.frscroll.h = data->u.dir.dirFndrInfo.frScroll.h;
469 ent->u.dir.view = data->u.dir.dirUsrInfo.frView;
474 ent->flags = (data->u.fil.filFlags & (1 << 0)) ? HFS_ISLOCKED : 0;
475 ent->cnid = data->u.fil.filFlNum;
477 ent->crdate = d_toutime(data->u.fil.filCrDat);
478 ent->mddate = d_toutime(data->u.fil.filMdDat);
479 ent->bkdate = d_toutime(data->u.fil.filBkDat);
481 ent->fdflags = data->u.fil.filUsrWds.fdFlags;
482 ent->fdlocation.v = data->u.fil.filUsrWds.fdLocation.v;
483 ent->fdlocation.h = data->u.fil.filUsrWds.fdLocation.h;
485 ent->u.file.dsize = data->u.fil.filLgLen;
486 ent->u.file.rsize = data->u.fil.filRLgLen;
488 d_putl((unsigned char *) ent->u.file.type,
489 data->u.fil.filUsrWds.fdType);
490 d_putl((unsigned char *) ent->u.file.creator,
491 data->u.fil.filUsrWds.fdCreator);
493 ent->u.file.type[4] = ent->u.file.creator[4] = 0;
500 * NAME: record->packdirent()
501 * DESCRIPTION: make changes to a catalog record
505 void r_packdirent(CatDataRec *data, hfsdirent *ent)
507 switch (data->cdrType)
510 data->u.dir.dirCrDat = d_tomtime(ent->crdate);
511 data->u.dir.dirMdDat = d_tomtime(ent->mddate);
512 data->u.dir.dirBkDat = d_tomtime(ent->bkdate);
514 data->u.dir.dirUsrInfo.frFlags = ent->fdflags;
515 data->u.dir.dirUsrInfo.frLocation.v = ent->fdlocation.v;
516 data->u.dir.dirUsrInfo.frLocation.h = ent->fdlocation.h;
518 data->u.dir.dirUsrInfo.frRect.top = ent->u.dir.rect.top;
519 data->u.dir.dirUsrInfo.frRect.left = ent->u.dir.rect.left;
520 data->u.dir.dirUsrInfo.frRect.bottom = ent->u.dir.rect.bottom;
521 data->u.dir.dirUsrInfo.frRect.right = ent->u.dir.rect.right;
524 data->u.dir.dirFndrInfo.frScroll.v = ent->u.dir.frscroll.v;
525 data->u.dir.dirFndrInfo.frScroll.h = ent->u.dir.frscroll.h;
526 data->u.dir.dirUsrInfo.frView = ent->u.dir.view;
531 if (ent->flags & HFS_ISLOCKED)
532 data->u.fil.filFlags |= (1 << 0);
534 data->u.fil.filFlags &= ~(1 << 0);
536 data->u.fil.filCrDat = d_tomtime(ent->crdate);
537 data->u.fil.filMdDat = d_tomtime(ent->mddate);
538 data->u.fil.filBkDat = d_tomtime(ent->bkdate);
540 data->u.fil.filUsrWds.fdFlags = ent->fdflags;
541 data->u.fil.filUsrWds.fdLocation.v = ent->fdlocation.v;
542 data->u.fil.filUsrWds.fdLocation.h = ent->fdlocation.h;
544 data->u.fil.filUsrWds.fdType =
545 d_getl((unsigned char *) ent->u.file.type);
546 data->u.fil.filUsrWds.fdCreator =
547 d_getl((unsigned char *) ent->u.file.creator);