Bug Summary

File:src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/apple.c
Warning:line 795, column 10
Access to field 'id' results in a dereference of a null pointer (loaded from variable 'ep')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name apple.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/obj -resource-dir /usr/local/lib/clang/13.0.0 -D SYSTEM_ID_DEFAULT="OpenBSD" -D APPLE_HYB -D VANILLA_AUTOCONF -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/include -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/libhfs_iso -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/libfile -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/apple.c
1/*
2** Unix-HFS file interface including maping file extensions to TYPE/CREATOR
3**
4** Adapted from mkhfs routines for mkhybrid
5**
6** James Pearson 1/5/97
7** Bug fix JCP 4/12/97
8** Updated for 1.12 and added more Unix HFS filetypes. JCP 21/1/98
9**
10** Things still to de done:
11**
12** Check SGI (XINET) structs
13** Check file size = finder + rsrc [+ data] is needed
14** AppleSingle/Double version 2?
15** Clean up byte order swapping.
16*/
17
18#ifdef APPLE_HYB1
19
20#include <ctype.h>
21#include <errno(*__errno()).h>
22#include <unistd.h>
23#include <err.h>
24#include <fcntl.h>
25#include <config.h>
26#include <stdlib.h>
27#include <sys/types.h>
28#include <netinet/in.h>
29#include <apple.h>
30#include "apple_proto.h"
31#include <mkisofs.h>
32
33/* tidy up mkisofs definition ... */
34typedef struct directory_entry dir_ent;
35
36/* routines for getting HFS names and info */
37static int get_none_dir(char *, char *, dir_ent *, int);
38static int get_none_info(char *, char *, dir_ent *, int);
39static int get_cap_dir(char *, char *, dir_ent *, int);
40static int get_cap_info(char *, char *, dir_ent *, int);
41static int get_es_info(char *, char *, dir_ent *, int);
42static int get_dbl_info(char *, char *, dir_ent *, int);
43static int get_mb_info(char *, char *, dir_ent *, int);
44static int get_sgl_info(char *, char *, dir_ent *, int);
45static int get_fe_dir(char *, char *, dir_ent *, int);
46static int get_fe_info(char *, char *, dir_ent *, int);
47static int get_sgi_dir(char *, char *, dir_ent *, int);
48static int get_sgi_info(char *, char *, dir_ent *, int);
49
50void map_ext(char *, char **, char **, unsigned short *, char *);
51static afpmap **map; /* list of mappings */
52static afpmap *defmap; /* the default mapping */
53static int last_ent; /* previous mapped entry */
54static int map_num; /* number of mappings */
55static int mlen; /* min extension length */
56static char tmp[MAXPATHLEN1024]; /* tmp working buffer */
57static int hfs_num; /* number of file types */
58static char p_buf[MAXPATHLEN1024]; /* info working buffer */
59static FILE *p_fp = NULL((void *)0); /* probe File pointer */
60static int p_num = 0; /* probe bytes read */
61static unsigned int hselect; /* type of HFS file selected */
62
63struct hfs_type { /* Types of various HFS Unix files */
64 int type; /* type of file */
65 int flags; /* special flags */
66 char *info; /* finderinfo name */
67 char *rsrc; /* resource fork name */
68 int (*get_info)(char*, char*, dir_ent*,int); /* finderinfo function */
69 int (*get_dir)(char*, char*,dir_ent*,int); /* directory name function */
70 char *desc; /* description */
71};
72
73/* Above filled in */
74static struct hfs_type hfs_types[] = {
75 {TYPE_NONE0,0,"", "", get_none_info, get_none_dir,"None"},
76 {TYPE_CAP1,0,".finderinfo/", ".resource/", get_cap_info, get_cap_dir,"CAP"},
77 {TYPE_NETA2,0,".AppleDouble/", ".AppleDouble/", get_dbl_info, get_none_dir,"Netatalk"},
78 {TYPE_DBL3,0,"%", "%", get_dbl_info, get_none_dir,"AppleDouble"},
79 {TYPE_ESH4, 0,".rsrc/", ".rsrc/", get_es_info, get_none_dir,"EtherShare/UShare"},
80 {TYPE_FEU5,2,"FINDER.DAT", "RESOURCE.FRK/", get_fe_info, get_fe_dir,"Exchange"},
81 {TYPE_FEL6,2,"finder.dat", "resource.frk/", get_fe_info, get_fe_dir,"Exchange"},
82 {TYPE_SGI7,2,".HSancillary", ".HSResource/", get_sgi_info, get_sgi_dir,"XINET/SGI"},
83 {TYPE_MBIN8,1,"", "", get_mb_info, get_none_dir,"MacBinary"},
84 {TYPE_SGL9,1,"", "", get_sgl_info, get_none_dir,"AppleSingle"}
85};
86
87/* used by get_magic_match() return */
88static char tmp_type[CT_SIZE4+1], tmp_creator[CT_SIZE4+1];
89
90/*
91** cstrncopy: Cap Unix name to HFS name
92**
93** ':' is replaced by '%' and string is terminated with '\0'
94*/
95void
96cstrncpy(char *t, char *f, int c)
97{
98 while (c-- && *f)
99 {
100 switch (*f)
101 {
102 case ':':
103 *t = '%';
104 break;
105 default:
106 *t = *f;
107 break;
108 }
109 t++; f++;
110 }
111
112 *t = '\0';
113}
114/*
115** dehex()
116**
117** Given a hexadecimal digit in ASCII, return the integer representation.
118**
119** Taken from linux/fs/hfs/trans.c by Paul H. Hargrove
120*/
121static unsigned char
122dehex(char c)
123{
124 if ((c>='0')&&(c<='9')) {
125 return c-'0';
126 }
127 if ((c>='a')&&(c<='f')) {
128 return c-'a'+10;
129 }
130 if ((c>='A')&&(c<='F')) {
131 return c-'A'+10;
132 }
133/* return 0xff; */
134 return (0);
135}
136
137static unsigned char
138hex2char(char *s)
139{
140 unsigned char o;
141
142 if(strlen(++s) < 2)
143 return(0);
144
145 if (!isxdigit(*s) || !isxdigit(*(s+1)))
146 return(0);
147
148 o = (dehex(*s) << 4) & 0xf0;
149 s++;
150 o |= (dehex(*s) & 0xf);
151
152 return (o);
153}
154
155/*
156** hstrncpy: Unix name to HFS name with special character
157** translation.
158**
159** "%xx" or ":xx" is assumed to be a "special" character and
160** replaced by character code given by the hex characters "xx"
161**
162** if "xx" is not a hex number, then it is left alone - except
163** that ":" is replaced by "%"
164**
165*/
166void
167hstrncpy(unsigned char *t, char *f, int c)
168{
169 unsigned char o;
170 while (c-- && *f)
171 {
172 switch (*f)
173 {
174 case ':':
175 case '%':
176 if ((o = hex2char(f)) == 0) {
177 *t = '%';
178 }
179 else {
180 *t = o;
181 f += 2;
182 }
183 break;
184 default:
185 *t = *f;
186 break;
187 }
188 t++; f++;
189 }
190
191 *t = '\0';
192}
193
194/*
195** basename: find just the filename with any directory component
196*/
197/* not used at the moment ...
198static char
199basename(char *a)
200{
201 char *b;
202
203 if((b = strchr(a, '/')))
204 return(++b);
205 else
206 return(a);
207}
208*/
209
210/*
211** get_none_dir: ordinary Unix directory
212*/
213int
214get_none_dir(char *hname, char *dname, dir_ent *s_entry, int ret)
215{
216 /* just copy the given name */
217 hstrncpy(s_entry->hfs_ent->name, dname, HFS_MAX_FLEN31);
218
219 return(ret);
220}
221
222/*
223** get_none_info: ordinary Unix file - try to map extension
224*/
225int
226get_none_info(char *hname, char *dname, dir_ent *s_entry, int ret)
227{
228 char *t, *c;
229 hfsdirent *hfs_ent = s_entry->hfs_ent;
230
231 map_ext(dname, &t, &c, &s_entry->hfs_ent->fdflags, s_entry->whole_name);
232
233 /* just copy the given name */
234 hstrncpy(hfs_ent->name, dname, HFS_MAX_FLEN31);
235
236 strncpy(hfs_ent->type, t, CT_SIZE4);
237 strncpy(hfs_ent->creator, c, CT_SIZE4);
238 hfs_ent->type[CT_SIZE4] = '\0';
239 hfs_ent->creator[CT_SIZE4] = '\0';
240
241 return(ret);
242}
243/*
244** read_info_file: open and read a finderinfo file for an HFS file
245** or directory
246*/
247int
248read_info_file(char *name, void *info, int len)
249/* char *name; finderinfo filename */
250/* void *info; info buffer */
251/* int len; length of above */
252{
253 FILE *fp;
254 int num;
255
256 /* clear out any old finderinfo stuf */
257 memset(info, 0, len);
258
259 if ((fp = fopen(name,"rb")) == NULL((void *)0))
260 return(-1);
261
262 /* read and ignore if the file is short - checked later */
263 num = fread(info,1,len,fp);
264
265 fclose(fp);
266
267 return(num);
268}
269/*
270** get_cap_dir: get the CAP name for a directory
271*/
272int
273get_cap_dir(char *hname, char *dname, dir_ent *s_entry, int ret)
274/* char *hname whole path */
275/* char *dname this dir name */
276/* dir_ent *s_entry directory entry */
277{
278 FileInfo info; /* finderinfo struct */
279 int num = -1; /* bytes read */
280
281 num = read_info_file(hname, &info, sizeof(FileInfo));
282
283 /* check finder info is OK */
284 if (num > 0
285 && info.fi_magic1 == FI_MAGIC1255
286 && info.fi_magic == FI_MAGIC0xda
287 && info.fi_bitmap & FI_BM_MACINTOSHFILENAME0x2) {
288 /* use the finderinfo name if it exists */
289 cstrncpy(s_entry->hfs_ent->name, info.fi_macfilename, HFS_MAX_FLEN31);
290 return (ret);
291 }
292 else {
293 /* otherwise give it it's Unix name */
294 hstrncpy(s_entry->hfs_ent->name, dname, HFS_MAX_FLEN31);
295 return (TYPE_NONE0);
296 }
297}
298
299/*
300** get_cap_info: get CAP finderinfo for a file
301*/
302int
303get_cap_info(char *hname, char *dname, dir_ent *s_entry, int ret)
304/* char *hname whole path */
305/* char *dname this dir name */
306/* dir_ent *s_entry directory entry */
307{
308 FileInfo info; /* finderinfo struct */
309 int num = -1; /* bytes read */
310 char *c;
311 char *t;
312 hfsdirent *hfs_ent = s_entry->hfs_ent;
313
314 num = read_info_file(hname, &info, sizeof(info));
315
316 /* check finder info is OK */
317 if (num > 0
318 && info.fi_magic1 == FI_MAGIC1255
319 && info.fi_magic == FI_MAGIC0xda) {
320
321 if (info.fi_bitmap & FI_BM_MACINTOSHFILENAME0x2) {
322 /* use the finderinfo name if it exists */
323 cstrncpy(hfs_ent->name, info.fi_macfilename, HFS_MAX_FLEN31);
324 }
325 else {
326 /* use Unix name */
327 hstrncpy(hfs_ent->name, dname, HFS_MAX_FLEN31);
328 }
329
330 /* type and creator from finder info */
331 t = info.fdType;
332 c = info.fdCreator;
333
334 strncpy(hfs_ent->type, t, CT_SIZE4);
335 strncpy(hfs_ent->creator, c, CT_SIZE4);
336 hfs_ent->type[CT_SIZE4] = '\0';
337 hfs_ent->creator[CT_SIZE4] = '\0';
338
339 /* finder flags */
340 hfs_ent->fdflags = d_getw((unsigned char *)&info.fdFlags);
341 /* clear HFS_FNDR_HASBEENINITED to have tidy desktop ?? */
342 hfs_ent->fdflags &= 0xfeff;
343
344#ifdef USE_MAC_DATES
345 /* set created/modified dates - these date should have already
346 been set from the Unix data fork dates. The finderinfo dates
347 are in Mac format - but we have to convert them back to Unix
348 for the time being */
349 if ((info.fi_datemagic & FI_CDATE0x02)) {
350 /* use libhfs routines to get correct byte order */
351 hfs_ent->crdate = d_toutime(d_getl(info.fi_ctime));
352 }
353 if (info.fi_datemagic & FI_MDATE0x01) {
354 hfs_ent->mddate = d_toutime(d_getl(info.fi_mtime));
355 }
356#endif /* USE_MAC_DATES */
357 }
358 else {
359 /* failed to open/read finderinfo - so try afpfile mapping */
360 if (verbose > 2) {
361 fprintf(stderr(&__sF[2]), "warning: %s doesn't appear to be a %s file\n",
362 s_entry->whole_name, hfs_types[ret].desc);
363 }
364
365 ret = get_none_info(hname, dname, s_entry, TYPE_NONE0);
366 }
367
368 return (ret);
369}
370
371/*
372** get_es_info: get EtherShare/UShare finderinfo for a file
373**
374** based on code from Jens-Uwe Mager (jum@helios.de) and Phil Sylvester
375** <psylvstr@interaccess.com>
376*/
377int
378get_es_info(char *hname, char *dname, dir_ent *s_entry, int ret)
379/* char *hname whole path */
380/* char *dname this dir name */
381/* dir_ent *s_entry directory entry */
382{
383 es_FileInfo *einfo; /* EtherShare info struct */
384 us_FileInfo *uinfo; /* UShare info struct */
385 char info[ES_INFO_SIZE512]; /* finderinfo buffer */
386 int num = -1; /* bytes read */
387 char *c;
388 char *t;
389 hfsdirent *hfs_ent = s_entry->hfs_ent;
390 dir_ent *s_entry1;
391
392 /* the EtherShare and UShare file layout is the same, but they
393 store finderinfo differently */
394 einfo = (es_FileInfo *)info;
395 uinfo = (us_FileInfo *)info;
396
397 num = read_info_file(hname, info, sizeof(info));
398
399 /* check finder info for EtherShare finderinfo */
400 if (num >= sizeof(es_FileInfo) &&
401 ntohl(einfo->magic)(__uint32_t)(__builtin_constant_p(einfo->magic) ? (__uint32_t
)(((__uint32_t)(einfo->magic) & 0xff) << 24 | ((
__uint32_t)(einfo->magic) & 0xff00) << 8 | ((__uint32_t
)(einfo->magic) & 0xff0000) >> 8 | ((__uint32_t)
(einfo->magic) & 0xff000000) >> 24) : __swap32md
(einfo->magic))
== ES_MAGIC0x3681093 &&
402 ntohs(einfo->version)(__uint16_t)(__builtin_constant_p(einfo->version) ? (__uint16_t
)(((__uint16_t)(einfo->version) & 0xffU) << 8 | (
(__uint16_t)(einfo->version) & 0xff00U) >> 8) : __swap16md
(einfo->version))
== ES_VERSION0x0102) {
403
404 /* type and creator from finder info */
405 t = einfo->fdType;
406 c = einfo->fdCreator;
407
408 /* finder flags */
409 hfs_ent->fdflags = d_getw((unsigned char *)&einfo->fdFlags);
410
411 /* set create date - modified date set from the Unix data
412 fork date */
413 hfs_ent->crdate = d_getl((unsigned char *)&einfo->createTime);
414 }
415 else if (num >= sizeof(us_FileInfo)) {
416 /* UShare has no magic number, so we assume that this is
417 a valid info/resource file ... */
418
419 /* type and creator from finder info */
420 t = uinfo->fdType;
421 c = uinfo->fdCreator;
422
423 /* finder flags */
424 hfs_ent->fdflags = d_getw((unsigned char *)&uinfo->fdFlags);
425
426 /* set create and modified date - if they exist */
427 if (uinfo->ctime)
428 hfs_ent->crdate = d_getl((unsigned char *)&uinfo->ctime);
429
430 if (uinfo->mtime)
431 hfs_ent->mddate = d_getl((unsigned char *)&uinfo->mtime);
432 }
433 else {
434 /* failed to open/read finderinfo - so try afpfile mapping */
435 if (verbose > 2) {
436 fprintf(stderr(&__sF[2]), "warning: %s doesn't appear to be a %s file\n",
437 s_entry->whole_name, hfs_types[ret].desc);
438 }
439
440 ret = get_none_info(hname, dname, s_entry, TYPE_NONE0);
441 return (ret);
442 }
443
444 /* this should exist ... */
445 if ((s_entry1 = s_entry->assoc) == NULL((void *)0))
446 errx(1, "TYPE_ESH error - shouldn't happen!");
447
448 /* fill in the HFS info stuff */
449 strncpy(hfs_ent->type, t, CT_SIZE4);
450 strncpy(hfs_ent->creator, c, CT_SIZE4);
451 hfs_ent->type[CT_SIZE4] = '\0';
452 hfs_ent->creator[CT_SIZE4] = '\0';
453
454 /* clear HFS_FNDR_HASBEENINITED to have tidy desktop ?? */
455 hfs_ent->fdflags &= 0xfeff;
456
457 /* set name */
458 hstrncpy(hfs_ent->name, dname, HFS_MAX_FLEN31);
459
460 /* real rsrc file starts ES_INFO_SIZE bytes into the file */
461 if(s_entry1->size <= ES_INFO_SIZE512) {
462 s_entry1->size = 0;
463 hfs_ent->rsize = 0;
464 }
465 else {
466 s_entry1->size -= ES_INFO_SIZE512;
467 hfs_ent->rsize = s_entry1->size;
468 s_entry1->hfs_off = ES_INFO_SIZE512;
469 }
470
471 set_733((char *) s_entry1->isorec.size, s_entry1->size);
472
473 return (ret);
474}
475
476/*
477 * calc_crc() --
478 * Compute the MacBinary II-style CRC for the data pointed to by p, with the
479 * crc seeded to seed.
480 *
481 * Modified by Jim Van Verth to use the magic array for efficiency.
482 */
483static unsigned short
484calc_mb_crc(unsigned char *p, long len, unsigned short seed)
485{
486 unsigned short hold; /* crc computed so far */
487 long i; /* index into data */
488
489 hold = seed; /* start with seed */
490 for (i = 0; i < len; i++, p++) {
491 hold ^= (*p << 8);
492 hold = (hold << 8) ^ mb_magic[(unsigned char)(hold >> 8)];
493 }
494
495 return (hold);
496} /* calc_mb_crc() */
497
498int
499get_mb_info(char *hname, char *dname, dir_ent *s_entry, int ret)
500/* char *hname whole path */
501/* char *dname this dir name */
502/* dir_ent *s_entry directory entry */
503{
504 mb_info *info; /* finderinfo struct */
505 char *c;
506 char *t;
507 hfsdirent *hfs_ent;
508 dir_ent *s_entry1;
509 int i;
510#ifdef TEST_CODE
511 unsigned short crc_file, crc_calc;
512#endif
513
514 info = (mb_info *)p_buf;
515
516 /* routine called twice for each file - first to check that
517 it is a valid MacBinary file, second to fill in the HFS
518 info. p_buf holds the required raw data and it *should*
519 remain the same between the two calls */
520
521 if (s_entry == 0) {
522 /* test that the CRC is OK - not set for MacBinary I files
523 (and incorrect in some MacBinary II files!). If this
524 fails, then perform some other checks */
525
526#ifdef TEST_CODE
527 /* leave this out for the time being ... */
528 if (p_num >= MB_SIZE128 && info->version == 0 && info->zero1 == 0) {
529 crc_calc = calc_mb_crc((unsigned char *)info, 124, 0);
530 crc_file = d_getw(info->crc);
531#ifdef DEBUG
532 fprintf(stderr(&__sF[2]),"%s: file %d, calc %d\n",hname,crc_file,crc_calc);
533#endif /* DEBUG */
534 if (crc_file == crc_calc)
535 return (ret);
536 }
537#endif /* TEST_CODE */
538
539 /* check some of the fields for a valid MacBinary file
540 not zero1 and zero2 SHOULD be zero - but some files incorrect */
541
542/* if (p_num < MB_SIZE || info->nlen > 63 || info->zero2 || */
543 if (p_num < MB_SIZE128 || info->zero1 ||
544 info->zero2 || info->nlen > 63 ||
545 info->version || info->nlen == 0 || *info->name == 0)
546 return (TYPE_NONE0);
547
548 /* check that the filename is OKish */
549 for (i=0;i<info->nlen;i++)
550 if(info->name[i] == 0)
551 return (TYPE_NONE0);
552
553 /* check CREATOR and TYPE are valid */
554 for (i=0;i<4;i++)
555 if(info->type[i] == 0 || info->auth[i] == 0)
556 return (TYPE_NONE0);
557 }
558 else {
559 /* we have a vaild MacBinary file, so fill in the bits */
560
561 /* this should exist ... */
562 if((s_entry1 = s_entry->assoc) == NULL((void *)0))
563 errx(1, "TYPE_MBIN error - shouldn't happen!");
564
565 hfs_ent = s_entry->hfs_ent;
566
567 /* type and creator from finder info */
568 t = info->type;
569 c = info->auth;
570
571 strncpy(hfs_ent->type, t, CT_SIZE4);
572 strncpy(hfs_ent->creator, c, CT_SIZE4);
573 hfs_ent->type[CT_SIZE4] = '\0';
574 hfs_ent->creator[CT_SIZE4] = '\0';
575
576 /* finder flags */
577 hfs_ent->fdflags = ((info->flags << 8) & 0xff00) | info->flags2;
578 /* clear HFS_FNDR_HASBEENINITED to have tidy desktop ?? */
579 hfs_ent->fdflags &= 0xfeff;
580
581 /* set created/modified dates - these date should have already
582 been set from the Unix data fork dates. The finderinfo dates
583 are in Mac format - but we have to convert them back to Unix
584 for the time being */
585
586 hfs_ent->crdate = d_toutime(d_getl(info->cdate));
587 hfs_ent->mddate = d_toutime(d_getl(info->mdate));
588
589 /* set name */
590/* hstrncpy(hfs_ent->name, info->name, HFS_MAX_FLEN); */
591 hstrncpy(hfs_ent->name, info->name, MIN(HFS_MAX_FLEN, info->nlen)(((31)<(info->nlen))?(31):(info->nlen)));
592
593 /* set correct fork sizes */
594 hfs_ent->dsize = d_getl(info->dflen);
595 hfs_ent->rsize = d_getl(info->rflen);
596
597 /* update directory entries for data fork */
598 s_entry->size = hfs_ent->dsize;
599 s_entry->hfs_off = MB_SIZE128;
600 set_733((char *) s_entry->isorec.size, s_entry->size);
601
602 /* real rsrc file starts after data fork (must be a multiple
603 of MB_SIZE) */
604 s_entry1->size = hfs_ent->rsize;
605 s_entry1->hfs_off = MB_SIZE128 + V_ROUND_UP(hfs_ent->dsize, MB_SIZE)(((hfs_ent->dsize + (128 - 1)) / 128) * 128);
606 set_733((char *) s_entry1->isorec.size, s_entry1->size);
607 }
608
609 return (ret);
610}
611
612/*
613** get_dbl_info: get Apple double finderinfo for a file
614**
615** Based on code from cvt2cap.c (c) May 1988, Paul Campbell
616*/
617int
618get_dbl_info(char *hname, char *dname, dir_ent *s_entry, int ret)
619/* char *hname whole path */
620/* char *dname this dir name */
621/* dir_ent *s_entry directory entry */
622{
623 FileInfo info; /* finderinfo struct */
624 a_hdr *hp;
625 a_entry *ep;
626 int num = -1; /* bytes read */
627 char *c;
628 char *t;
629 int nentries;
630 FILE *fp;
631 hfsdirent *hfs_ent = s_entry->hfs_ent;
632 dir_ent *s_entry1;
633 char name[64];
634 int i;
635 int fail = 0;
636
637 hp = (a_hdr *)p_buf;;
638 memset(hp, 0, A_HDR_SIZE26);
639
640 memset(name, 0, sizeof(name));
641
642 /* get the rsrc file info - should exist ... */
643 if ((s_entry1 = s_entry->assoc) == NULL((void *)0))
644 errx(1, "TYPE_DBL error - shouldn't happen!");
645
646 /* open and read the info/rsrc file (it's the same file) */
647 if ((fp = fopen(hname,"rb")) != NULL((void *)0))
648 num = fread(hp, 1, A_HDR_SIZE26, fp);
649
650 /* check finder info is OK - some Netatalk files don't have
651 magic or version set - ignore if it's a netatalk file */
652 if (num == A_HDR_SIZE26 && ((ret == TYPE_NETA2) ||
653 (ntohl(hp->magic)(__uint32_t)(__builtin_constant_p(hp->magic) ? (__uint32_t
)(((__uint32_t)(hp->magic) & 0xff) << 24 | ((__uint32_t
)(hp->magic) & 0xff00) << 8 | ((__uint32_t)(hp->
magic) & 0xff0000) >> 8 | ((__uint32_t)(hp->magic
) & 0xff000000) >> 24) : __swap32md(hp->magic))
== APPLE_DOUBLE0x00051607 &&
654 ntohl(hp->version)(__uint32_t)(__builtin_constant_p(hp->version) ? (__uint32_t
)(((__uint32_t)(hp->version) & 0xff) << 24 | ((__uint32_t
)(hp->version) & 0xff00) << 8 | ((__uint32_t)(hp
->version) & 0xff0000) >> 8 | ((__uint32_t)(hp->
version) & 0xff000000) >> 24) : __swap32md(hp->version
))
== A_VERSION0x00010000))) {
655
656 /* read TOC of the AppleDouble file */
657 nentries = (int)ntohs(hp->nentries)(__uint16_t)(__builtin_constant_p(hp->nentries) ? (__uint16_t
)(((__uint16_t)(hp->nentries) & 0xffU) << 8 | ((
__uint16_t)(hp->nentries) & 0xff00U) >> 8) : __swap16md
(hp->nentries))
;
658 if(fread(hp->entries, A_ENTRY_SIZEsizeof(a_entry), nentries, fp) < 1) {
659 fail = 1;
660 nentries = 0;
661 }
662
663 /* extract what is needed */
664 for (i=0, ep=hp->entries; i<nentries; i++,ep++) {
665 switch(ntohl(ep->id)(__uint32_t)(__builtin_constant_p(ep->id) ? (__uint32_t)((
(__uint32_t)(ep->id) & 0xff) << 24 | ((__uint32_t
)(ep->id) & 0xff00) << 8 | ((__uint32_t)(ep->
id) & 0xff0000) >> 8 | ((__uint32_t)(ep->id) &
0xff000000) >> 24) : __swap32md(ep->id))
) {
666 case ID_FINDER9:
667 /* get the finder info */
668 fseek(fp, ntohl(ep->offset)(__uint32_t)(__builtin_constant_p(ep->offset) ? (__uint32_t
)(((__uint32_t)(ep->offset) & 0xff) << 24 | ((__uint32_t
)(ep->offset) & 0xff00) << 8 | ((__uint32_t)(ep->
offset) & 0xff0000) >> 8 | ((__uint32_t)(ep->offset
) & 0xff000000) >> 24) : __swap32md(ep->offset))
, 0);
669 if (fread(&info, ntohl(ep->length)(__uint32_t)(__builtin_constant_p(ep->length) ? (__uint32_t
)(((__uint32_t)(ep->length) & 0xff) << 24 | ((__uint32_t
)(ep->length) & 0xff00) << 8 | ((__uint32_t)(ep->
length) & 0xff0000) >> 8 | ((__uint32_t)(ep->length
) & 0xff000000) >> 24) : __swap32md(ep->length))
, 1, fp) < 1) {
670 fail = 1;
671 }
672 break;
673 case ID_RESOURCE2:
674 /* set the offset and correct rsrc fork size */
675 s_entry1->size = ntohl(ep->length)(__uint32_t)(__builtin_constant_p(ep->length) ? (__uint32_t
)(((__uint32_t)(ep->length) & 0xff) << 24 | ((__uint32_t
)(ep->length) & 0xff00) << 8 | ((__uint32_t)(ep->
length) & 0xff0000) >> 8 | ((__uint32_t)(ep->length
) & 0xff000000) >> 24) : __swap32md(ep->length))
;
676 hfs_ent->rsize = s_entry1->size;
677 /* offset to start of real rsrc fork */
678 s_entry1->hfs_off = ntohl(ep->offset)(__uint32_t)(__builtin_constant_p(ep->offset) ? (__uint32_t
)(((__uint32_t)(ep->offset) & 0xff) << 24 | ((__uint32_t
)(ep->offset) & 0xff00) << 8 | ((__uint32_t)(ep->
offset) & 0xff0000) >> 8 | ((__uint32_t)(ep->offset
) & 0xff000000) >> 24) : __swap32md(ep->offset))
;
679 set_733((char *) s_entry1->isorec.size, s_entry1->size);
680 break;
681 case ID_NAME3:
682 /* get Mac file name */
683 fseek(fp, ntohl(ep->offset)(__uint32_t)(__builtin_constant_p(ep->offset) ? (__uint32_t
)(((__uint32_t)(ep->offset) & 0xff) << 24 | ((__uint32_t
)(ep->offset) & 0xff00) << 8 | ((__uint32_t)(ep->
offset) & 0xff0000) >> 8 | ((__uint32_t)(ep->offset
) & 0xff000000) >> 24) : __swap32md(ep->offset))
, 0);
684 if(fread(name, ntohl(ep->length)(__uint32_t)(__builtin_constant_p(ep->length) ? (__uint32_t
)(((__uint32_t)(ep->length) & 0xff) << 24 | ((__uint32_t
)(ep->length) & 0xff00) << 8 | ((__uint32_t)(ep->
length) & 0xff0000) >> 8 | ((__uint32_t)(ep->length
) & 0xff000000) >> 24) : __swap32md(ep->length))
, 1, fp) < 1)
685 *name = '\0';
686 break;
687 default:
688 break;
689 }
690 }
691
692 fclose(fp);
693
694 /* skip this if we had a problem */
695 if (!fail) {
696 /* type and creator from finder info */
697 t = info.fdType;
698 c = info.fdCreator;
699
700 strncpy(hfs_ent->type, t, CT_SIZE4);
701 strncpy(hfs_ent->creator, c, CT_SIZE4);
702 hfs_ent->type[CT_SIZE4] = '\0';
703 hfs_ent->creator[CT_SIZE4] = '\0';
704
705 /* finder flags */
706 hfs_ent->fdflags = d_getw((unsigned char *)&info.fdFlags);
707 /* clear HFS_FNDR_HASBEENINITED to have tidy desktop ?? */
708 hfs_ent->fdflags &= 0xfeff;
709
710 /* use stored name if it exists */
711 if (*name)
712 cstrncpy(hfs_ent->name, name, HFS_MAX_FLEN31);
713 else
714 hstrncpy(hfs_ent->name, dname, HFS_MAX_FLEN31);
715 }
716 }
717 else {
718 /* failed to open/read finderinfo */
719 fail = 1;
720 if (fp)
721 fclose(fp);
722 }
723
724 if (fail) {
725 /* problem with the file - try mapping/magic */
726 if (verbose > 2) {
727 fprintf(stderr(&__sF[2]), "warning: %s doesn't appear to be a %s file\n",
728 s_entry->whole_name, hfs_types[ret].desc);
729 }
730 ret = get_none_info(hname, dname, s_entry, TYPE_NONE0);
731 }
732
733 return (ret);
734}
735/*
736** get_sgl_info: get Apple single finderinfo for a file
737**
738** Based on code from cvt2cap.c (c) May 1988, Paul Campbell
739*/
740int
741get_sgl_info(char *hname, char *dname, dir_ent *s_entry, int ret)
742/* char *hname whole path */
743/* char *dname this dir name */
744/* dir_ent *s_entry directory entry */
745{
746 FileInfo *info = 0; /* finderinfo struct */
747 a_hdr *hp;
748 static a_entry *entries;
1
'entries' initialized to a null pointer value
749 a_entry *ep;
750 char *c;
751 char *t;
752 int nentries;
753 hfsdirent *hfs_ent;
754 dir_ent *s_entry1;
755 char name[64];
756 int i;
757
758 /* routine called twice for each file - first to check that
759 it is a valid MacBinary file, second to fill in the HFS
760 info. p_buf holds the required raw data and it *should*
761 remain the same between the two calls */
762
763 hp = (a_hdr *)p_buf;
764
765 if (s_entry == 0) {
2
Assuming 's_entry' is not equal to null
3
Taking false branch
766 if (p_num < A_HDR_SIZE26 ||
767 ntohl(hp->magic)(__uint32_t)(__builtin_constant_p(hp->magic) ? (__uint32_t
)(((__uint32_t)(hp->magic) & 0xff) << 24 | ((__uint32_t
)(hp->magic) & 0xff00) << 8 | ((__uint32_t)(hp->
magic) & 0xff0000) >> 8 | ((__uint32_t)(hp->magic
) & 0xff000000) >> 24) : __swap32md(hp->magic))
!= APPLE_SINGLE0x00051600 ||
768 ntohl(hp->version)(__uint32_t)(__builtin_constant_p(hp->version) ? (__uint32_t
)(((__uint32_t)(hp->version) & 0xff) << 24 | ((__uint32_t
)(hp->version) & 0xff00) << 8 | ((__uint32_t)(hp
->version) & 0xff0000) >> 8 | ((__uint32_t)(hp->
version) & 0xff000000) >> 24) : __swap32md(hp->version
))
!= A_VERSION0x00010000)
769 return (TYPE_NONE0);
770
771 /* check we have TOC for the AppleSingle file */
772 nentries = (int)ntohs(hp->nentries)(__uint16_t)(__builtin_constant_p(hp->nentries) ? (__uint16_t
)(((__uint16_t)(hp->nentries) & 0xffU) << 8 | ((
__uint16_t)(hp->nentries) & 0xff00U) >> 8) : __swap16md
(hp->nentries))
;
773 if (p_num < (A_HDR_SIZE26 + nentries*A_ENTRY_SIZEsizeof(a_entry)))
774 return (TYPE_NONE0);
775
776 /* save the TOC */
777 entries = (a_entry *)e_malloc(nentries*A_ENTRY_SIZEsizeof(a_entry));
778
779 memcpy(entries, (p_buf+A_HDR_SIZE26), nentries*A_ENTRY_SIZEsizeof(a_entry));
780 }
781 else {
782 /* have a vaild AppleSingle File */
783 memset(name, 0, sizeof(name));
784
785 /* get the rsrc file info - should exist ... */
786 if ((s_entry1 = s_entry->assoc) == NULL((void *)0))
4
Assuming the condition is false
5
Taking false branch
787 errx(1, "TYPE_SGL error - shouldn't happen!");
788
789 hfs_ent = s_entry->hfs_ent;
790
791 nentries = (int)ntohs(hp->nentries)(__uint16_t)(__builtin_constant_p(hp->nentries) ? (__uint16_t
)(((__uint16_t)(hp->nentries) & 0xffU) << 8 | ((
__uint16_t)(hp->nentries) & 0xff00U) >> 8) : __swap16md
(hp->nentries))
;
6
'?' condition is false
792
793 /* extract what is needed */
794 for (i=0, ep=entries; i<nentries; i++,ep++) {
7
Null pointer value stored to 'ep'
8
Assuming 'i' is < 'nentries'
9
Loop condition is true. Entering loop body
795 switch(ntohl(ep->id)(__uint32_t)(__builtin_constant_p(ep->id) ? (__uint32_t)((
(__uint32_t)(ep->id) & 0xff) << 24 | ((__uint32_t
)(ep->id) & 0xff00) << 8 | ((__uint32_t)(ep->
id) & 0xff0000) >> 8 | ((__uint32_t)(ep->id) &
0xff000000) >> 24) : __swap32md(ep->id))
) {
10
Access to field 'id' results in a dereference of a null pointer (loaded from variable 'ep')
796 case ID_FINDER9:
797 /* get the finder info */
798 info = (FileInfo *)(p_buf + ntohl(ep->offset)(__uint32_t)(__builtin_constant_p(ep->offset) ? (__uint32_t
)(((__uint32_t)(ep->offset) & 0xff) << 24 | ((__uint32_t
)(ep->offset) & 0xff00) << 8 | ((__uint32_t)(ep->
offset) & 0xff0000) >> 8 | ((__uint32_t)(ep->offset
) & 0xff000000) >> 24) : __swap32md(ep->offset))
);
799 break;
800 case ID_DATA1:
801 /* set the offset and correct data fork size */
802 hfs_ent->dsize = s_entry->size = ntohl(ep->length)(__uint32_t)(__builtin_constant_p(ep->length) ? (__uint32_t
)(((__uint32_t)(ep->length) & 0xff) << 24 | ((__uint32_t
)(ep->length) & 0xff00) << 8 | ((__uint32_t)(ep->
length) & 0xff0000) >> 8 | ((__uint32_t)(ep->length
) & 0xff000000) >> 24) : __swap32md(ep->length))
;
803 /* offset to start of real data fork */
804 s_entry->hfs_off = ntohl(ep->offset)(__uint32_t)(__builtin_constant_p(ep->offset) ? (__uint32_t
)(((__uint32_t)(ep->offset) & 0xff) << 24 | ((__uint32_t
)(ep->offset) & 0xff00) << 8 | ((__uint32_t)(ep->
offset) & 0xff0000) >> 8 | ((__uint32_t)(ep->offset
) & 0xff000000) >> 24) : __swap32md(ep->offset))
;
805 set_733((char *) s_entry->isorec.size, s_entry->size);
806 break;
807 case ID_RESOURCE2:
808 /* set the offset and correct rsrc fork size */
809 hfs_ent->rsize = s_entry1->size = ntohl(ep->length)(__uint32_t)(__builtin_constant_p(ep->length) ? (__uint32_t
)(((__uint32_t)(ep->length) & 0xff) << 24 | ((__uint32_t
)(ep->length) & 0xff00) << 8 | ((__uint32_t)(ep->
length) & 0xff0000) >> 8 | ((__uint32_t)(ep->length
) & 0xff000000) >> 24) : __swap32md(ep->length))
;
810 /* offset to start of real rsrc fork */
811 s_entry1->hfs_off = ntohl(ep->offset)(__uint32_t)(__builtin_constant_p(ep->offset) ? (__uint32_t
)(((__uint32_t)(ep->offset) & 0xff) << 24 | ((__uint32_t
)(ep->offset) & 0xff00) << 8 | ((__uint32_t)(ep->
offset) & 0xff0000) >> 8 | ((__uint32_t)(ep->offset
) & 0xff000000) >> 24) : __swap32md(ep->offset))
;
812 set_733((char *) s_entry1->isorec.size, s_entry1->size);
813 break;
814 case ID_NAME3:
815 strncpy(name, (p_buf+ntohl(ep->offset)(__uint32_t)(__builtin_constant_p(ep->offset) ? (__uint32_t
)(((__uint32_t)(ep->offset) & 0xff) << 24 | ((__uint32_t
)(ep->offset) & 0xff00) << 8 | ((__uint32_t)(ep->
offset) & 0xff0000) >> 8 | ((__uint32_t)(ep->offset
) & 0xff000000) >> 24) : __swap32md(ep->offset))
),
816 ntohl(ep->length)(__uint32_t)(__builtin_constant_p(ep->length) ? (__uint32_t
)(((__uint32_t)(ep->length) & 0xff) << 24 | ((__uint32_t
)(ep->length) & 0xff00) << 8 | ((__uint32_t)(ep->
length) & 0xff0000) >> 8 | ((__uint32_t)(ep->length
) & 0xff000000) >> 24) : __swap32md(ep->length))
);
817 break;
818 default:
819 break;
820 }
821 }
822
823 free(entries);
824
825 if (info == NULL((void *)0)) {
826 /* failed to open/read finderinfo - so try afpfile mapping */
827 if (verbose > 2) {
828 fprintf(stderr(&__sF[2]), "warning: %s doesn't appear to be a %s file\n",
829 s_entry->whole_name, hfs_types[ret].desc);
830 }
831 ret = get_none_info(hname, dname, s_entry, TYPE_NONE0);
832 return (ret);
833 }
834
835 /* type and creator from finder info */
836 t = info->fdType;
837 c = info->fdCreator;
838
839 strncpy(hfs_ent->type, t, CT_SIZE4);
840 strncpy(hfs_ent->creator, c, CT_SIZE4);
841 hfs_ent->type[CT_SIZE4] = '\0';
842 hfs_ent->creator[CT_SIZE4] = '\0';
843
844 /* finder flags */
845 hfs_ent->fdflags = d_getw((unsigned char *)&info->fdFlags);
846 /* clear HFS_FNDR_HASBEENINITED to have tidy desktop ?? */
847 hfs_ent->fdflags &= 0xfeff;
848
849 /* use stored name if it exists */
850 if (*name)
851 cstrncpy(hfs_ent->name, name, HFS_MAX_FLEN31);
852 else
853 hstrncpy(hfs_ent->name, dname, HFS_MAX_FLEN31);
854 }
855
856 return (ret);
857}
858
859/*
860** get_hfs_fe_info: read in the whole finderinfo for a PC Exchange
861** directory - saves on reading this many times for each file.
862**
863** Based of information provided by Mark Weinstein <mrwesq@earthlink.net>
864**
865** Note: the FINDER.DAT file layout depends on the FAT cluster size
866** therefore, files should only be read directly from the FAT media
867**
868** Only tested with PC Exchange v2.1 - don't know if it will work
869** with v2.2 and above.
870*/
871struct hfs_info *
872get_hfs_fe_info(struct hfs_info *hfs_info, char *name)
873{
874 FILE *fp;
875#ifdef __svr4__
876 struct statvfs fsbuf;
877#else
878 struct statfs fsbuf;
879#endif /* __svr4__ */
880 int fe_num, fe_pad;
881 fe_info info;
882 int c = 0;
883 struct hfs_info *hfs_info1 = NULL((void *)0);
884 hfsdirent *hfs_ent;
885 char keyname[12];
886 char *s, *e, *k;
887 int i;
888
889 if ((fp = fopen(name, "rb")) == NULL((void *)0))
890 return(NULL((void *)0));
891
892 /* The FAT cluster size may have been given on the command line
893 - if not they try and find *guess* it */
894 if (!bsize) {
895 /* FINDER.DAT layout depends on the FAT cluster size - assume
896 this is mapped to the "fundamental file system block size"
897 For SVR4 we use statvfs(), others use statfs() */
898#ifdef __svr4__
899 if (statvfs(name, &fsbuf) < 0)
900 return(NULL((void *)0));
901
902 bsize = fsbuf.f_frsize;
903#else
904 if (statfs(name, &fsbuf) < 0)
905 return(NULL((void *)0));
906
907 bsize = fsbuf.f_bsize;
908#endif /* __svr4__ */
909 }
910
911 if (bsize <= 0)
912 return(NULL((void *)0));
913
914 fe_num = bsize/FE_SIZE92;
915 fe_pad = bsize%FE_SIZE92;
916
917 while(fread(&info, 1, FE_SIZE92, fp) != 0) {
918
919 /* the Mac name may be NULL - so ignore this entry */
920 if (info.nlen != 0) {
921
922 hfs_info1 = (struct hfs_info *)e_malloc(sizeof(struct hfs_info));
923 /* add this entry to the list */
924 hfs_info1->next = hfs_info;
925 hfs_info = hfs_info1;
926
927 hfs_ent = &hfs_info1->hfs_ent;
928
929 /* get the bits we need - ignore [cm]time for the moment */
930 cstrncpy(hfs_ent->name, info.name, info.nlen);
931
932 strncpy(hfs_ent->type, info.type, CT_SIZE4);
933 strncpy(hfs_ent->creator, info.creator, CT_SIZE4);
934
935 hfs_ent->type[CT_SIZE4] = hfs_ent->creator[CT_SIZE4] = '\0';
936
937 hfs_ent->fdflags = d_getw(info.flags);
938
939 s = info.sname;
940 e = info.ext;
941 k = keyname;
942
943 /* short (Unix) name is stored in PC format, so needs
944 to be mangled a bit */
945
946 /* name part */
947 for(i=0;i<8;i++,s++,k++) {
948 if(*s == ' ')
949 break;
950 else
951 *k = *s;
952 }
953
954 /* extension - if it exists */
955 if (strncmp(info.ext, " ", 3)) {
956 *k = '.';
957 k++;
958 for(i=0;i<3;i++,e++,k++) {
959 if(*e == ' ')
960 break;
961 else
962 *k = *e;
963 }
964 }
965 *k = '\0';
966
967 hfs_info1->keyname = strdup(keyname);
968 }
969
970 /* each record is FE_SIZE long, and there are FE_NUM
971 per each "cluster size", so we may need to skip the padding */
972 if (++c == fe_num) {
973 c = 0;
974 fseek(fp, fe_pad, 1);
975 }
976 }
977 fclose (fp);
978
979 return (hfs_info);
980}
981
982/*
983** get_hfs_sgi_info: read in the whole finderinfo for a SGI (XINET)
984** directory - saves on reading this many times for each
985** file.
986*/
987struct hfs_info *
988get_hfs_sgi_info(struct hfs_info *hfs_info, char *name)
989{
990 FILE *fp;
991 sgi_info info;
992 struct hfs_info *hfs_info1 = NULL((void *)0);
993 hfsdirent *hfs_ent;
994
995 if ((fp = fopen(name, "rb")) == NULL((void *)0))
996 return(NULL((void *)0));
997
998 while(fread(&info, 1, SGI_SIZE300, fp) != 0) {
999
1000 hfs_info1 = (struct hfs_info *)e_malloc(sizeof(struct hfs_info));
1001 /* add thsi entry to the list */
1002 hfs_info1->next = hfs_info;
1003 hfs_info = hfs_info1;
1004
1005 hfs_ent = &hfs_info1->hfs_ent;
1006
1007 /* get the bits we need - ignore [cm]time for the moment */
1008 cstrncpy(hfs_ent->name, info.name, HFS_MAX_FLEN31);
1009
1010 strncpy(hfs_ent->type, info.type, CT_SIZE4);
1011 strncpy(hfs_ent->creator, info.creator, CT_SIZE4);
1012
1013 hfs_ent->type[CT_SIZE4] = hfs_ent->creator[CT_SIZE4] = '\0';
1014
1015 /* don't know about flags at the moment */
1016 /* hfs_ent->fdflags = d_getw((unsigned char *)&info.flags); */
1017
1018 /* use the HFS name as the key */
1019 hfs_info1->keyname = hfs_ent->name;
1020
1021 }
1022 fclose (fp);
1023
1024 return (hfs_info);
1025}
1026
1027/*
1028** del_hfs_info: delete the info list and recover memory
1029*/
1030void
1031del_hfs_info(struct hfs_info *hfs_info)
1032{
1033 struct hfs_info *hfs_info1;
1034
1035 while (hfs_info) {
1036 hfs_info1 = hfs_info;
1037 hfs_info = hfs_info->next;
1038
1039 /* key may be the same as the HFS name - so don't free it */
1040 *hfs_info1->hfs_ent.name = '\0';
1041 if (*hfs_info1->keyname)
1042 free(hfs_info1->keyname);
1043 free(hfs_info1);
1044 }
1045}
1046
1047/*
1048** match_key: find the correct hfs_ent using the Unix filename
1049** as the key
1050*/
1051hfsdirent *
1052match_key(struct hfs_info *hfs_info, char *key)
1053{
1054 while (hfs_info) {
1055 if (!strcasecmp(key, hfs_info->keyname))
1056 return (&hfs_info->hfs_ent);
1057 hfs_info = hfs_info->next;
1058 }
1059
1060 return (NULL((void *)0));
1061}
1062
1063/*
1064** get_fe_dir: get PC Exchange directory name
1065**
1066** base on probing with od ...
1067*/
1068int
1069get_fe_dir(char *hname, char *dname, dir_ent *s_entry, int ret)
1070/* char *hname whole path */
1071/* char *dname this dir name */
1072/* dir_ent *s_entry directory entry */
1073{
1074 struct hfs_info *hfs_info;
1075 hfsdirent *hfs_ent;
1076
1077 /* cached finderinfo stored with parent directory */
1078 hfs_info = s_entry->filedir->hfs_info;
1079
1080 /* if we have no cache, then make one and store it */
1081 if (hfs_info == NULL((void *)0)) {
1082 if ((hfs_info = get_hfs_fe_info(hfs_info, hname)) == NULL((void *)0))
1083 ret = TYPE_NONE0;
1084 else
1085 s_entry->filedir->hfs_info = hfs_info;
1086 }
1087
1088 if (ret != TYPE_NONE0) {
1089 /* see if we can find the details of this file */
1090 if ((hfs_ent = match_key(hfs_info, dname)) != NULL((void *)0)) {
1091 strcpy(s_entry->hfs_ent->name, hfs_ent->name);
1092 return (ret);
1093 }
1094 }
1095
1096 /* can't find the entry, so use the Unix name */
1097 hstrncpy(s_entry->hfs_ent->name, dname, HFS_MAX_FLEN31);
1098
1099 return(TYPE_NONE0);
1100}
1101
1102/*
1103** get_fe_info: get PC Exchange file details.
1104**
1105** base on probing with od and details from Mark Weinstein
1106** <mrwesq@earthlink.net>
1107*/
1108int
1109get_fe_info(char *hname, char *dname, dir_ent *s_entry, int ret)
1110/* char *hname whole path */
1111/* char *dname this dir name */
1112/* dir_ent *s_entry directory entry */
1113{
1114 struct hfs_info *hfs_info;
1115 hfsdirent *hfs_ent;
1116
1117 /* cached finderinfo stored with parent directory */
1118 hfs_info = s_entry->filedir->hfs_info;
1119
1120 /* if we have no cache, then make one and store it */
1121 if (hfs_info == NULL((void *)0)) {
1122 if ((hfs_info = get_hfs_fe_info(hfs_info, hname)) == NULL((void *)0))
1123 ret = TYPE_NONE0;
1124 else
1125 s_entry->filedir->hfs_info = hfs_info;
1126 }
1127
1128 if (ret != TYPE_NONE0) {
1129 char *dn = dname;
1130#ifdef _WIN32_TEST
1131 /* may have a problem here - v2.2 has long filenames,
1132 but we need to key on the short filename, so we need
1133 do go a bit of win32 stuff ... */
1134
1135 char sname[1024], lname[1024];
1136
1137 cygwin32_conv_to_full_win32_path(s_entry->whole_name, lname);
1138
1139 if (GetShortPathName(lname, sname, sizeof(sname))) {
1140 if (dn = strrchr(sname, '\\'))
1141 dn++;
1142 else
1143 dn = sname;
1144 }
1145#endif /* _WIN32 */
1146
1147 /* see if we can find the details of this file */
1148 if ((hfs_ent = match_key(hfs_info, dn)) != NULL((void *)0)) {
1149 strcpy(s_entry->hfs_ent->name, hfs_ent->name);
1150 strcpy(s_entry->hfs_ent->type, hfs_ent->type);
1151 strcpy(s_entry->hfs_ent->creator, hfs_ent->creator);
1152 /* clear HFS_FNDR_HASBEENINITED flag */
1153 s_entry->hfs_ent->fdflags = hfs_ent->fdflags & 0xfeff;
1154 return (ret);
1155 }
1156 }
1157
1158 /* no entry found - use extension mapping */
1159 if (verbose > 2) {
1160 fprintf(stderr(&__sF[2]), "warning: %s doesn't appear to be a %s file\n",
1161 s_entry->whole_name, hfs_types[ret].desc);
1162 }
1163
1164 ret = get_none_info(hname, dname, s_entry, TYPE_NONE0);
1165
1166 return(TYPE_NONE0);
1167}
1168
1169/*
1170** get_sgi_dir: get SGI (XINET) HFS directory name
1171**
1172** base on probing with od ...
1173*/
1174int
1175get_sgi_dir(char *hname, char *dname, dir_ent *s_entry, int ret)
1176/* char *hname whole path */
1177/* char *dname this dir name */
1178/* dir_ent *s_entry directory entry */
1179{
1180 struct hfs_info *hfs_info;
1181 hfsdirent *hfs_ent;
1182
1183 /* cached finderinfo stored with parent directory */
1184 hfs_info = s_entry->filedir->hfs_info;
1185
1186 /* if we haven't got a cache, then make one */
1187 if (hfs_info == NULL((void *)0)) {
1188 if ((hfs_info = get_hfs_sgi_info(hfs_info, hname)) == NULL((void *)0))
1189 ret = TYPE_NONE0;
1190 else
1191 s_entry->filedir->hfs_info = hfs_info;
1192 }
1193
1194 /* find the matching entry in the cache */
1195 if (ret != TYPE_NONE0) {
1196 /* key is (hopefully) the real Mac name */
1197 cstrncpy(tmp, dname, strlen(dname));
1198 if ((hfs_ent = match_key(hfs_info, tmp)) != NULL((void *)0)) {
1199 strcpy(s_entry->hfs_ent->name, hfs_ent->name);
1200 return (ret);
1201 }
1202 }
1203
1204 /* no entry found - use Unix name */
1205 hstrncpy(s_entry->hfs_ent->name, dname, HFS_MAX_FLEN31);
1206
1207 return(TYPE_NONE0);
1208}
1209
1210/*
1211** get_sgi_info: get SGI (XINET) HFS finder info
1212**
1213** base on probing with od ...
1214*/
1215int
1216get_sgi_info(char *hname, char *dname, dir_ent *s_entry, int ret)
1217/* char *hname whole path */
1218/* char *dname this dir name */
1219/* dir_ent *s_entry directory entry */
1220{
1221 struct hfs_info *hfs_info;
1222 hfsdirent *hfs_ent;
1223
1224 /* cached finderinfo stored with parent directory */
1225 hfs_info = s_entry->filedir->hfs_info;
1226
1227 /* if we haven't got a cache, then make one */
1228 if (hfs_info == NULL((void *)0)) {
1229 if ((hfs_info = get_hfs_sgi_info(hfs_info, hname)) == NULL((void *)0))
1230 ret = TYPE_NONE0;
1231 else
1232 s_entry->filedir->hfs_info = hfs_info;
1233 }
1234
1235 if (ret != TYPE_NONE0) {
1236 /* tmp is the same as hname here, but we don't need hname
1237 anymore in this function ... see if we can find the
1238 details of this file using the Unix name as the key */
1239 cstrncpy(tmp, dname, strlen(dname));
1240 if ((hfs_ent = match_key(hfs_info, tmp)) != NULL((void *)0)) {
1241 strcpy(s_entry->hfs_ent->name, hfs_ent->name);
1242 strcpy(s_entry->hfs_ent->type, hfs_ent->type);
1243 strcpy(s_entry->hfs_ent->creator, hfs_ent->creator);
1244 /* s_entry->hfs_ent->fdflags = hfs_ent->fdflags; */
1245 return (ret);
1246 }
1247 }
1248
1249 /* no entry found, so try file extension */
1250 if (verbose > 2) {
1251 fprintf(stderr(&__sF[2]), "warning: %s doesn't appear to be a %s file\n",
1252 s_entry->whole_name, hfs_types[ret].desc);
1253 }
1254
1255 ret = get_none_info(hname, dname, s_entry, TYPE_NONE0);
1256
1257 return(TYPE_NONE0);
1258}
1259
1260/*
1261** get_hfs_itype: get the type of HFS info for a file
1262*/
1263int
1264get_hfs_itype(char *wname, char *dname, char *htmp)
1265{
1266 int wlen, i;
1267
1268 wlen = strlen(wname) - strlen(dname);
1269
1270 /* search through the known types looking for matches */
1271 for (i=1;i<hfs_num;i++) {
1272 /* skip the ones that we don't care about */
1273 if ((hfs_types[i].flags & 0x1) || *(hfs_types[i].info) == TYPE_NONE0)
1274 continue;
1275
1276 strcpy(htmp, wname);
1277
1278 sprintf(htmp+wlen, "%s%s", hfs_types[i].info,
1279 (hfs_types[i].flags & 0x2) ? "" : dname);
1280 if (!access(tmp, R_OK0x04))
1281 return (hfs_types[i].type);
1282 }
1283
1284 return (TYPE_NONE0);
1285}
1286
1287/*
1288** get_hfs_dir: set the HFS directory name
1289*/
1290int
1291get_hfs_dir(char *wname, char *dname, dir_ent *s_entry)
1292{
1293 int type;
1294
1295 /* get the HFS file type from the info file (if it exists) */
1296 type = get_hfs_itype(wname, dname, tmp);
1297
1298 /* try to get the required info */
1299 type = (*(hfs_types[type].get_dir))(tmp, dname, s_entry, type);
1300
1301 return (type);
1302}
1303
1304/*
1305** get_hfs_info: set the HFS info for a file
1306*/
1307int
1308get_hfs_info(char *wname, char *dname, dir_ent *s_entry)
1309{
1310 int type, wlen, i;
1311
1312 wlen = strlen(wname) - strlen(dname);
1313
1314 /* we may already know the type of Unix/HFS file - so process */
1315 if (s_entry->hfs_type != TYPE_NONE0) {
1316
1317/*
1318 i = 0;
1319 for(type=1;i<hfs_num;type++) {
1320 if (s_entry->hfs_type == hfs_types[type].type) {
1321 i = type;
1322 break;
1323 }
1324 }
1325*/
1326 type = s_entry->hfs_type;
1327
1328 strcpy(tmp, wname);
1329 sprintf(tmp+wlen, "%s%s", hfs_types[type].info,
1330 (hfs_types[type].flags & 0x2) ? "" : dname);
1331 type = (*(hfs_types[type].get_info))(tmp, dname, s_entry, type);
1332
1333 /* if everything is as expected, then return */
1334 if (s_entry->hfs_type == type)
1335 return(type);
1336 }
1337
1338 /* we don't know what type we have so, find out */
1339 for (i=1;i<hfs_num;i++) {
1340 if ((hfs_types[i].flags & 0x1) || *(hfs_types[i].info) == TYPE_NONE0)
1341 continue;
1342
1343 strcpy(tmp, wname);
1344
1345 sprintf(tmp+wlen, "%s%s", hfs_types[i].info,
1346 (hfs_types[i].flags & 0x2) ? "" : dname);
1347
1348 /* if the file exists - and not a type we've already tried */
1349 if (!access(tmp, R_OK0x04) && i != s_entry->hfs_type) {
1350 type = (*(hfs_types[i].get_info))(tmp, dname, s_entry, i);
1351 s_entry->hfs_type = type;
1352 return (type);
1353 }
1354 }
1355
1356 /* nothing found, so just a Unix file */
1357 type = (*(hfs_types[TYPE_NONE0].get_info))(wname, dname, s_entry, TYPE_NONE0);
1358
1359 return (type);
1360}
1361
1362/*
1363** get_hfs_rname: set the name of the Unix rsrc file for a file
1364*/
1365int
1366get_hfs_rname(char *wname, char *dname, char *rname)
1367{
1368 int wlen, type, i;
1369 int p_fd = -1;
1370
1371 wlen = strlen(wname) - strlen(dname);
1372
1373 /* try to find what sort of Unix HFS file type we have */
1374 for (i=1;i<hfs_num;i++) {
1375 /* skip if don't want to probe the files - (default) */
1376 if (hfs_types[i].flags & 0x1)
1377 continue;
1378
1379 strcpy(rname, wname);
1380
1381 /* if we have a different info file, the find out it's type */
1382 if (*(hfs_types[i].rsrc)) {
1383 sprintf(rname+wlen, "%s%s", hfs_types[i].rsrc, dname);
1384 if (!access(rname, R_OK0x04))
1385 return (hfs_types[i].type);
1386 }
1387 else {
1388 /* if we are probing, then have a look at the contents to
1389 find type */
1390 if (p_fd < 0) {
1391 /* open file, if not already open */
1392 if((p_fd = open(wname, O_RDONLY0x0000 | O_BINARY0)) < 0) {
1393 /* can't open it, then give up */
1394 return (TYPE_NONE0);
1395 } else {
1396 if((p_num = read(p_fd, p_buf, sizeof(p_buf))) <= 0) {
1397 /* can't read, or zero length - give up */
1398 close(p_fd);
1399 return(TYPE_NONE0);
1400 }
1401 /* get file pointer and close file */
1402 p_fp = fdopen(p_fd, "rb");
1403 close(p_fd);
1404 if(p_fp == NULL((void *)0))
1405 return(TYPE_NONE0);
1406 }
1407 }
1408 /* call routine to do the work - use the given dname as
1409 this is the name we may use on the CD */
1410 type = (*(hfs_types[i].get_info))(rname, dname, 0, i);
1411 if (type != 0) {
1412 fclose(p_fp);
1413 return (type);
1414 }
1415 if (p_fp) {
1416 /* close file - just use contents of buffer next time */
1417 fclose(p_fp);
1418 p_fp = NULL((void *)0);
1419 }
1420 }
1421 }
1422
1423 return (0);
1424}
1425
1426/*
1427** hfs_exclude: file/directory names that hold finder/resource
1428** information that we want to exclude from the tree.
1429** These files/directories are processed later ...
1430*/
1431int
1432hfs_exclude(char *d_name)
1433{
1434 /* we don't exclude "." and ".." */
1435 if (!strcmp(d_name,"."))
1436 return 0;
1437 if (!strcmp(d_name,".."))
1438 return 0;
1439
1440 /* do not add the following to our list of dir entries */
1441 if (DO_CAP(1 << 1) & hselect) {
1442 /* CAP */
1443 if(!strcmp(d_name,".finderinfo"))
1444 return 1;
1445 if(!strcmp(d_name,".resource"))
1446 return 1;
1447 if(!strcmp(d_name,".ADeskTop"))
1448 return 1;
1449 if(!strcmp(d_name,".IDeskTop"))
1450 return 1;
1451 if(!strcmp(d_name,"Network Trash Folder"))
1452 return 1;
1453 /* special case when HFS volume is mounted using Linux's hfs_fs
1454 Brad Midgley <brad@pht.com> */
1455 if(!strcmp(d_name,".rootinfo"))
1456 return 1;
1457 }
1458
1459 if (DO_ESH(1 << 4) & hselect) {
1460 /* Helios EtherShare files */
1461 if(!strcmp(d_name,".rsrc"))
1462 return 1;
1463 if(!strcmp(d_name,".Desktop"))
1464 return 1;
1465 if(!strcmp(d_name,".DeskServer"))
1466 return 1;
1467 if(!strcmp(d_name,".Label"))
1468 return 1;
1469 }
1470
1471 if (DO_DBL(1 << 3) & hselect) {
1472 /* Apple Double */
1473 if (*d_name == '%')
1474 return 1;
1475 }
1476
1477 if (DO_NETA(1 << 2) & hselect) {
1478 if(!strcmp(d_name,".AppleDouble"))
1479 return 1;
1480 if(!strcmp(d_name,".AppleDesktop"))
1481 return 1;
1482 }
1483
1484 if ((DO_FEU(1 << 5) & hselect) || ( DO_FEL(1 << 6) & hselect)) {
1485 /* PC Exchange */
1486 if(!strcmp(d_name,"RESOURCE.FRK"))
1487 return 1;
1488 if(!strcmp(d_name,"FINDER.DAT"))
1489 return 1;
1490 if(!strcmp(d_name,"DESKTOP"))
1491 return 1;
1492 if(!strcmp(d_name,"FILEID.DAT"))
1493 return 1;
1494 if(!strcmp(d_name,"resource.frk"))
1495 return 1;
1496 if(!strcmp(d_name,"finder.dat"))
1497 return 1;
1498 if(!strcmp(d_name,"desktop"))
1499 return 1;
1500 if(!strcmp(d_name,"fileid.dat"))
1501 return 1;
1502 }
1503
1504 if (DO_SGI(1 << 7) | hselect) {
1505 /* SGI */
1506 if(!strcmp(d_name,".HSResource"))
1507 return 1;
1508 if(!strcmp(d_name,".HSancillary"))
1509 return 1;
1510 }
1511
1512 return 0;
1513}
1514/*
1515** print_hfs_info: print info about the HFS files.
1516**
1517*/
1518void
1519print_hfs_info(dir_ent *s_entry)
1520{
1521 fprintf(stderr(&__sF[2]),"Name: %s\n",s_entry->whole_name);
1522 fprintf(stderr(&__sF[2]),"\tFile type: %s\n",hfs_types[s_entry->hfs_type].desc);
1523 fprintf(stderr(&__sF[2]),"\tHFS Name: %s\n",s_entry->hfs_ent->name);
1524 fprintf(stderr(&__sF[2]),"\tISO Name: %s\n",s_entry->isorec.name);
1525 fprintf(stderr(&__sF[2]),"\tCREATOR: %s\n",s_entry->hfs_ent->creator);
1526 fprintf(stderr(&__sF[2]),"\tTYPE: %s\n", s_entry->hfs_ent->type);
1527}
1528
1529
1530/*
1531** hfs_init: sets up the mapping list from the afpfile as well
1532** the default mapping (with or without) an afpfile
1533*/
1534void
1535hfs_init(char *name, unsigned short fdflags, int probe, int nomacfiles,
1536 unsigned int hfs_select)
1537#if 0
1538 char *name; /* afpfile name */
1539 u_short *fdflags; /* default finder flags */
1540 int probe; /* probe flag */
1541 int nomacfiles; /* don't look for mac files */
1542 u_int hfs_select /* select certain mac files */
1543#endif
1544{
1545 FILE *fp; /* File pointer */
1546 int count = NUMMAP512; /* max number of entries */
1547 char buf[MAXPATHLEN1024]; /* working buffer */
1548 afpmap *amap; /* mapping entry */
1549 char *c, *t, *e;
1550 int i;
1551
1552 /* setup number of Unix/HFS filetype - we may wish to not bother */
1553 if (nomacfiles)
1554 hfs_num = 0;
1555 else
1556 hfs_num = sizeof(hfs_types)/sizeof(struct hfs_type);
1557
1558 /* we may want to probe all files */
1559 if (probe || hfs_select)
1560 for(i=0;i<hfs_num;i++)
1561 hfs_types[i].flags &= ~1; /* 0xfffffffe */
1562
1563 /* if we have selected certain types of Mac/Unix files, then
1564 turn off the filetype */
1565 if (hfs_select)
1566 for(i=1;i<hfs_num;i++)
1567 if (!((1 << i) & hfs_select))
1568 hfs_types[i].flags |= 0x1;
1569
1570 /* save what types have been selected (set all if none have) */
1571 if (hfs_select)
1572 hselect = hfs_select;
1573 else
1574 hselect = ~0;
1575
1576#ifdef DEBUG
1577 for(i=0;i<hfs_num;i++)
1578 fprintf(stderr(&__sF[2]),"type = %d flags = %d\n", i, hfs_types[i].flags);
1579#endif /* DEBUG */
1580
1581 /* min length set to max to start with */
1582 mlen = MAXPATHLEN1024;
1583
1584 /* initialise magic file */
1585 if(magic_file && init_magic(magic_file) != 0)
1586 errx(1, "unable to open magic file");
1587
1588 /* set defaults */
1589 map_num = last_ent = 0;
1590
1591 /* allocate memory for the default entry */
1592 if((defmap = (afpmap *)malloc(sizeof(afpmap))) == NULL((void *)0))
1593 errx(1, "not enough memory");
1594
1595 /* set default values */
1596 defmap->extn = DEFMATCH"*";
1597
1598 /* make sure creator and type are 4 chars long */
1599 strcpy(defmap->type, BLANK" ");
1600 strcpy(defmap->creator, BLANK" ");
1601
1602 e = deftype;
1603 t = defmap->type;
1604
1605 while(*e && (e - deftype) < CT_SIZE4)
1606 *t++ = *e++;
1607
1608 e = defcreator;
1609 c = defmap->creator;
1610
1611 while(*e && (e - defcreator) < CT_SIZE4)
1612 *c++ = *e++;
1613
1614 /* length is not important here */
1615 defmap->elen = 0;
1616
1617 /* no flags */
1618 defmap->fdflags = fdflags;
1619
1620 /* no afpfile - no mappings */
1621 if (*name == '\0') {
1622 map = NULL((void *)0);
1623 return;
1624 }
1625
1626 if((fp = fopen(name,"r")) == NULL((void *)0))
1627 err(1, "unable to open mapping file: %s", name);
1628
1629 if((map = (afpmap **)malloc(NUMMAP512 * sizeof(afpmap *))) == NULL((void *)0))
1630 errx(1, "not enough memory");
1631
1632 /* read afpfile line by line */
1633 while(fgets(buf, MAXPATHLEN1024, fp) != NULL((void *)0)) {
1634 /* ignore any comment lines */
1635 c = tmp;
1636 *c = '\0';
1637 if (sscanf(buf,"%1s", c) == EOF(-1) || *c == '#')
1638 continue;
1639
1640 /* increase list size if needed */
1641 if (map_num == count) {
1642 count += NUMMAP512;
1643 map = (afpmap **)realloc(map, count * sizeof(afpmap *));
1644 if (map == NULL((void *)0))
1645 errx(1, "not enough memory");
1646 }
1647
1648 /* allocate memory for this entry */
1649 if((amap = (afpmap *)malloc(sizeof(afpmap))) == NULL((void *)0))
1650 errx(1, "not enough memory");
1651
1652 t = amap->type;
1653 c = amap->creator;
1654
1655 /* extract the info */
1656 if(sscanf(buf, "%s%*s%*1s%c%c%c%c%*1s%*1s%c%c%c%c%*1s",
1657 tmp, c, c+1, c+2, c+3, t, t+1, t+2, t+3) != 9) {
1658 fprintf(stderr(&__sF[2]),"error scanning afpfile %s - continuing", name);
1659 free(amap);
1660 continue;
1661 }
1662
1663 /* copy the extension found */
1664 if ((amap->extn = (char *)strdup(tmp)) == NULL((void *)0))
1665 errx(1, "not enough memory");
1666
1667 /* set end-of-string */
1668 *(t+4) = *(c+4) = '\0';
1669
1670 /* find the length of the extension */
1671 amap->elen = strlen(amap->extn);
1672
1673 /* set flags */
1674 amap->fdflags = fdflags;
1675
1676 /* see if we have the default creator/type */
1677 if(!strcmp(amap->extn, DEFMATCH"*")) {
1678 /* get rid of the old default */
1679 free(defmap);
1680 /* make this the default */
1681 defmap = amap;
1682 continue;
1683 }
1684
1685 /* update the smallest extension length */
1686 mlen = MIN(mlen, amap->elen)(((mlen)<(amap->elen))?(mlen):(amap->elen));
1687
1688 /* add entry to the list */
1689 map[map_num++] = amap;
1690
1691 }
1692
1693 /* free up some memory */
1694 if (map_num != count) {
1695 map = (afpmap **)realloc(map, map_num * sizeof(afpmap *));
1696 if (map == NULL((void *)0))
1697 errx(1, "not enough memory");
1698 }
1699
1700}
1701
1702/*
1703** map_ext: map a files extension with the list to get type/creator
1704*/
1705void
1706map_ext(char *name, char **type, char **creator, unsigned short *fdflags,
1707 char *whole_name)
1708#if 0
1709 char *name; /* filename */
1710 char **type; /* set type */
1711 char **creator; /* set creator */
1712 u_short *fdflags; /* set finder flags */
1713#endif
1714{
1715 int i; /* loop counter */
1716 int len; /* filename length */
1717 afpmap *amap; /* mapping entry */
1718 char *ret;
1719
1720 /* we don't take fdflags from the map or magic file */
1721 *fdflags = defmap->fdflags;
1722
1723 /* if we have a magic file and we want to search it first, then
1724 try to get a match */
1725 if (magic_file && hfs_last == MAP_LAST1) {
1726 ret = get_magic_match(whole_name);
1727
1728 if (ret) {
1729 if (sscanf(ret, "%4s%4s", tmp_creator, tmp_type) == 2) {
1730 *type = tmp_type;
1731 *creator = tmp_creator;
1732 return;
1733 }
1734 }
1735 }
1736
1737 len = strlen(name);
1738
1739 /* have an afpfile and filename if long enough */
1740 if(map && len >= mlen) {
1741 /* search through the list - we start where we left
1742 off last time in case this file is of the same type
1743 as the last one */
1744 for(i=0;i<map_num;i++) {
1745 amap = map[last_ent];
1746
1747 /* compare the end of the filename */
1748/* if (!strcmp((name + len - amap->elen), amap->extn)) { */
1749 if (!strcasecmp((name + len - amap->elen), amap->extn)) {
1750 /* set the required info */
1751 *type = amap->type;
1752 *creator = amap->creator;
1753 *fdflags = amap->fdflags;
1754 return;
1755 }
1756 /* move on to the next entry - wrapping round if neccessary */
1757 last_ent++;
1758 last_ent %= map_num;
1759 }
1760 }
1761
1762 /* if no matches are found, file name too short, or no
1763 afpfile, then take defaults */
1764 *type = defmap->type;
1765 *creator = defmap->creator;
1766
1767 /* if we have a magic file and we haven't searched yet, then try
1768 to get a match */
1769 if (magic_file && hfs_last == MAG_LAST2) {
1770 ret = get_magic_match(whole_name);
1771
1772 if (ret) {
1773 if (sscanf(ret, "%4s%4s", tmp_creator, tmp_type) == 2) {
1774 *type = tmp_type;
1775 *creator = tmp_creator;
1776 }
1777 }
1778 }
1779}
1780
1781void
1782delete_rsrc_ent(dir_ent *s_entry)
1783{
1784 dir_ent *s_entry1 = s_entry->next;
1785
1786 if (s_entry1 == NULL((void *)0))
1787 return;
1788
1789 s_entry->next = s_entry1->next;
1790 s_entry->assoc = NULL((void *)0);
1791
1792 free(s_entry1->name);
1793 free(s_entry1->whole_name);
1794
1795 free(s_entry1);
1796}
1797
1798void
1799clean_hfs()
1800{
1801 if (map)
1802 free(map);
1803
1804 if (defmap)
1805 free(defmap);
1806
1807 if (magic_file)
1808 clean_magic();
1809}
1810
1811#else
1812#include <stdio.h>
1813#endif /* APPLE_HYB */