1 /* @(#)volume.c	1.25 10/12/19 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson, Copyright 2004-2010 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)volume.c	1.25 10/12/19 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson, Copyright 2004-2010 J. Schilling";
6 #endif
7 /*
8  *      Copyright (c) 1997, 1998, 1999, 2000 James Pearson
9  *	Copyright (c) 2004-2010 J. Schilling
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2, or (at your option)
14  * any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; see the file COPYING.  If not, write to
23  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25 
26 /*
27  *	volume.c: prepare HFS volume for mkhybrid
28  *
29  *	James Pearson 17/7/97
30  *	modified JCP 29/7/97 to improve allocation sizes to cut
31  *	down on wasted space. Now uses the HFS "allocation" size rounded
32  *	up to the nearest 2048 bytes. Savings can be significant with
33  *	a large volume containing lots of smallish files.
34  *
35  *	Updated for v1.12 - now uses the built in RELOCATED_DIRECTORY
36  *	flag for finding the real directory location JCP 8/1/97
37  */
38 
39 #ifdef APPLE_HFS_HYB
40 
41 #include "mkisofs.h"
42 #include <schily/errno.h>
43 #include <schily/schily.h>
44 
45 #define	HFS_MIN_SIZE	1600	/* 800k == 1600 HFS blocks */
46 
47 LOCAL hfsvol  *vol_save = 0;	/* used to "destroy" an HFS volume */
48 
49 LOCAL	int	AlcSiz		__PR((Ulong));
50 LOCAL	int	XClpSiz		__PR((Ulong));
51 LOCAL	int	get_vol_size	__PR((int));
52 EXPORT	int	write_fork	__PR((hfsfile * hfp, long tot));
53 EXPORT	int	make_mac_volume	__PR((struct directory *, UInt32_t));
54 LOCAL	int	copy_to_mac_vol	__PR((hfsvol *, struct directory *));
55 LOCAL void	set_dir_info	__PR((hfsvol *, struct directory *));
56 
57 /*
58  *	AlcSiz: find allocation size for given volume size
59  */
60 LOCAL int
AlcSiz(vlen)61 AlcSiz(vlen)
62 	Ulong	vlen;
63 {
64 	int	lpa,
65 		drAlBlkSiz;
66 
67 	/* code extracted from hfs_format() */
68 	lpa = 1 + vlen / 65536;
69 	drAlBlkSiz = lpa * HFS_BLOCKSZ;
70 
71 	/*
72 	 * now set our "allocation size" to the allocation block rounded up to
73 	 * the nearest SECTOR_SIZE (2048 bytes)
74 	 */
75 	drAlBlkSiz = ROUND_UP(drAlBlkSiz, SECTOR_SIZE);
76 
77 	return (drAlBlkSiz);
78 }
79 
80 /*
81  *	XClpSiz: find the default size of the catalog/extent file
82  */
83 LOCAL int
XClpSiz(vlen)84 XClpSiz(vlen)
85 	Ulong	vlen;
86 {
87 	int	olpa,
88 		lpa,
89 		drNmAlBlks,
90 		drAlBlkSiz;
91 	int	vbmsz,
92 		drXTClpSiz;
93 
94 	/* code extracted from hfs_format() */
95 
96 	/* get the lpa from our calculated allocation block size */
97 	drAlBlkSiz = AlcSiz(vlen);
98 	lpa = drAlBlkSiz / HFS_BLOCKSZ;
99 
100 	vbmsz = (vlen / lpa + 4095) / 4096;
101 	drNmAlBlks = (vlen - 5 - vbmsz) / lpa;
102 	drXTClpSiz = drNmAlBlks / 128 * drAlBlkSiz;
103 
104 	/* override the drXTClpSiz size for large volumes */
105 	if (drXTClpSiz > hce->max_XTCsize) {
106 		drXTClpSiz = hce->max_XTCsize;
107 	} else {
108 		/*
109 		 * make allowances because we have possibly rounded up the
110 		 * allocation size get the "original" lpa "
111 		 */
112 		olpa = 1 + vlen / 65536;
113 
114 		/* adjust size upwards */
115 		drXTClpSiz = ((Ullong)drXTClpSiz * lpa) / olpa;
116 	}
117 
118 	/* round up to the nearest allocation size */
119 	drXTClpSiz = ROUND_UP(drXTClpSiz, drAlBlkSiz);
120 
121 	return (drXTClpSiz);
122 }
123 
124 /*
125  *	get_vol_size: get the size of the volume including the extent/catalog
126  */
127 LOCAL int
get_vol_size(vblen)128 get_vol_size(vblen)
129 	int	vblen;
130 {
131 	int	drXTClpSiz;
132 	int	drAlBlkSiz;
133 	int	new_vblen;
134 
135 	/*
136 	 * try to estimate a "volume size" based on the code in hfs_format
137 	 * - we need the size of the catalog/extents and Desktop files included
138 	 * in the volume, as we add this to the end of the ISO volume
139 	 */
140 	drXTClpSiz = XClpSiz(vblen);
141 	drAlBlkSiz = AlcSiz(vblen);
142 
143 	/*
144 	 * catalog file is set at CTC times (default twice) the extents
145 	 * file size - hence the (ctc_size + 1) below. The Desktop starts of
146 	 * the same size as the "clump size" == 4 x drAlBlkSiz,
147 	 * plus a spare drAlBlkSiz for the alternative MDB
148 	 */
149 	new_vblen = vblen +
150 	    ((hce->ctc_size + 1) * drXTClpSiz + 5 * drAlBlkSiz) / HFS_BLOCKSZ;
151 
152 	return (new_vblen);
153 }
154 
155 /*
156  *	write_fork: "write" file data to the volume
157  *
158  *	This is used to update the HFS file internal structures
159  *	but no data is actually written (it's trapped deep down in
160  *	libhfs).
161  */
162 EXPORT int
write_fork(hfp,tot)163 write_fork(hfp, tot)
164 	hfsfile	*hfp;
165 	long	tot;
166 {
167 	char		blk[HFS_BLOCKSZ];
168 	unsigned short	start;
169 	long		len;
170 
171 	len = tot;
172 	/* we need to know where this fork starts */
173 	start = hfs_get_drAllocPtr(hfp);
174 
175 	/* loop through the data a block at a time */
176 	while (len >= HFS_BLOCKSZ) {
177 		if (hfs_write(hfp, blk, HFS_BLOCKSZ) < 0)
178 			return (-1);
179 		len -= HFS_BLOCKSZ;
180 	}
181 	/* write out anything left */
182 	if (len)
183 		if (hfs_write(hfp, blk, len) < 0)
184 			return (-1);
185 
186 	/*
187 	 * set the start of the allocation search to be immediately after
188 	 * this fork
189 	 */
190 	hfs_set_drAllocPtr(hfp, start, tot);
191 
192 	return (0);
193 }
194 
195 /*
196  *	make_mac_volume: "create" an HFS volume using the ISO data
197  *
198  *	The HFS volume structures are set up (but no data is written yet).
199  *
200  *	ISO volumes have a allocation size of 2048 bytes - regardless
201  *	of the size of the volume. HFS allocation size is depends on volume
202  *	size, so we may have to update the ISO structures to add in any
203  *	padding.
204  */
205 EXPORT int
make_mac_volume(dpnt,start_extent)206 make_mac_volume(dpnt, start_extent)
207 	struct directory	*dpnt;
208 	UInt32_t		start_extent;
209 {
210 	char	vol_name[HFS_MAX_VLEN + 1];	/* Mac volume name */
211 	hfsvol	*vol;			/* Mac volume */
212 	int	vblen;			/* vol length (HFS blocks) */
213 	int	Csize,
214 		lastCsize;		/* allocation sizes */
215 	int	ret = 0;		/* return value */
216 	int	loop = 1;
217 
218 	/* umount volume if we have had a previous attempt */
219 	if (vol_save)
220 		if (hfs_umount(vol_save, 0, hfs_lock) < 0)
221 			return (-1);
222 
223 	/* set the default clump size to the ISO block size */
224 	Csize = lastCsize = SECTOR_SIZE;
225 
226 	if (verbose > 1)
227 		fprintf(stderr, _("Creating HFS Volume info\n"));
228 
229 	/* name or copy ISO volume name to Mac Volume name */
230 	strncpy(vol_name, hfs_volume_id ? hfs_volume_id : volume_id,
231 								HFS_MAX_VLEN);
232 	vol_name[HFS_MAX_VLEN] = '\0';
233 
234 	/* get initial size of HFS volume (size of current ISO volume) */
235 	vblen = (last_extent - session_start) * HFS_BLK_CONV;
236 
237 	/* make sure volume is at least 800k */
238 	if (vblen < HFS_MIN_SIZE)
239 		vblen += insert_padding_file(HFS_MIN_SIZE - vblen);
240 
241 	/*
242 	 * add on size of extents/catalog file, but this may mean the
243 	 * allocation size will change, so loop round until the
244 	 * allocation size doesn't change
245 	 */
246 	while (loop) {
247 		hce->XTCsize = XClpSiz(vblen);
248 		vblen = get_vol_size(vblen);
249 		Csize = AlcSiz(vblen);
250 
251 		if (Csize == lastCsize) {
252 			/* allocation size hasn't changed, so carry on */
253 			loop = 0;
254 		} else {
255 			/*
256 			 * allocation size has changed, so update
257 			 * ISO volume size
258 			 */
259 			if ((vblen = get_adj_size(Csize)) < 0) {
260 				sprintf(hce->error,
261 					_("too many files for HFS volume"));
262 				return (-1);
263 			}
264 			vblen +=
265 				ROUND_UP((start_extent - session_start) *
266 						HFS_BLK_CONV, Csize);
267 			lastCsize = Csize;
268 		}
269 	}
270 
271 	/* take off the label/map size */
272 	vblen -= hce->hfs_map_size;
273 
274 	hce->hfs_vol_size = vblen;
275 
276 	/* set the default allocation size for libhfs */
277 	hce->Csize = Csize;
278 
279 	/* format and mount the "volume" */
280 	if (hfs_format(hce, 0, vol_name) < 0) {
281 		sprintf(hce->error, _("can't HFS format %s"), vol_name);
282 		return (-1);
283 	}
284 	/*
285 	 * update the ISO structures with new start extents and any
286 	 * padding required
287 	 */
288 	if (Csize != SECTOR_SIZE) {
289 		last_extent = adj_size(Csize, start_extent,
290 					hce->hfs_hdr_size + hce->hfs_map_size);
291 		adj_size_other(dpnt);
292 	}
293 	if ((vol = hfs_mount(hce, 0, 0)) == 0) {
294 		sprintf(hce->error, _("can't HFS mount %s"), vol_name);
295 		return (-1);
296 	}
297 	/* save the volume for possible later use */
298 	vol_save = vol;
299 
300 	/*
301 	 * Recursively "copy" the files to the volume
302 	 * - we need to know the first allocation block in the volume as
303 	 * starting blocks of files are relative to this.
304 	 */
305 	ret = copy_to_mac_vol(vol, dpnt);
306 	if (ret < 0)
307 		return (ret);
308 
309 	/*
310 	 * make the Desktop files - I *think* this stops the Mac rebuilding the
311 	 * desktop when the CD is mounted on a Mac These will be ignored if they
312 	 * already exist
313 	 */
314 	if (create_dt)
315 		ret = make_desktop(vol,
316 				(last_extent - session_start) * HFS_BLK_CONV);
317 	if (ret < 0)
318 		return (ret);
319 
320 	/* close the volume */
321 	if (hfs_flush(vol) < 0)
322 		return (-1);
323 
324 	/* unmount and set the start blocks for the catalog/extents files */
325 	if (hfs_umount(vol, (last_extent - session_start) * HFS_BLK_CONV, hfs_lock) < 0)
326 		return (-1);
327 
328 	return (Csize);
329 }
330 
331 #define	TEN 10	/* well, it is! */
332 #define	LCHAR "_"
333 
334 /*
335  *	copy_to_mac_vol: copy all files in a directory to corresponding
336  *			 Mac folder.
337  *
338  *	Files are copied recursively to corresponding folders on the Mac
339  *	volume. The caller routine needs to do a hfs_chdir before calling this
340  *	routine.
341  */
342 LOCAL int
copy_to_mac_vol(vol,node)343 copy_to_mac_vol(vol, node)
344 	hfsvol		*vol;
345 	struct directory *node;
346 {
347 	struct directory_entry	*s_entry;	/* ISO directory entry */
348 	struct directory_entry	*s_entry1;	/* tmp ISO directory entry */
349 	struct directory	*dpnt;		/* ISO directory */
350 
351 	hfsfile			*hfp;		/* HFS file */
352 	hfsdirent		*ent;		/* HFS file entities */
353 	long			id;		/* current HFS folder */
354 	long			dext,
355 				rext;		/* real data/rsrc start blk */
356 	int			ret;		/* result code */
357 	int			new_name;	/* HFS file has modified name */
358 
359 	int			tens;
360 	int			digits;
361 	int			i;
362 
363 	/* store the current HFS directory ID */
364 	if ((id = hfs_getcwd(vol)) == 0)
365 		return (-1);
366 
367 	if (verbose > 1)
368 		fprintf(stderr, _("HFS scanning %s\n"), node->whole_name);
369 
370 	/* loop through the ISO directory entries and process files */
371 	for (s_entry = node->contents; s_entry; s_entry = s_entry->next) {
372 		/* ignore directory and associated (rsrc) files */
373 		if (s_entry->isorec.flags[0] & (ISO_DIRECTORY|ISO_ASSOCIATED))
374 			continue;
375 
376 		/* ignore any non-Mac type file */
377 		if (!s_entry->hfs_ent)
378 			continue;
379 
380 		/*
381 		 * ignore if from a previous session
382 		 * - should be trapped above
383 		 */
384 		if (s_entry->starting_block < session_start)
385 			continue;
386 
387 #ifdef DEBUG
388 		fprintf(stderr, " Name = %s", s_entry->whole_name);
389 		fprintf(stderr, "   Startb =  %d\n", s_entry->starting_block);
390 #endif	/* DEBUG */
391 
392 		ent = s_entry->hfs_ent;
393 
394 		/* create file */
395 		i = HFS_MAX_FLEN - strlen(ent->name);
396 		new_name = 0;
397 		tens = TEN;
398 		digits = 1;
399 
400 		while (1) {
401 			/*
402 			 * try to open file - if it exists,
403 			 * then append '_' to the name and try again
404 			 */
405 			errno = 0;
406 			if ((hfs_create(vol, ent->name, ent->u.file.type,
407 						ent->u.file.creator)) < 0) {
408 				if (errno != EEXIST) {
409 					/*
410 					 * not an "exist" error, or we can't
411 					 * append as the filename is already
412 					 * HFS_MAX_FLEN chars
413 					 */
414 					sprintf(hce->error,
415 						_("can't HFS create file %s %s"),
416 						s_entry->whole_name, ent->name);
417 					return (-1);
418 				} else if (i == 0) {
419 					/*
420 					 * File name at max HFS length
421 					 * - make unique name
422 					 */
423 					if (!new_name)
424 						new_name++;
425 
426 					sprintf(ent->name +
427 						HFS_MAX_FLEN - digits - 1,
428 						"%s%d", LCHAR, new_name);
429 					new_name++;
430 					if (new_name == tens) {
431 						tens *= TEN;
432 						digits++;
433 					}
434 				} else {
435 					/* append '_' to get new name */
436 					strcat(ent->name, LCHAR);
437 					i--;
438 					new_name = 1;
439 				}
440 			} else
441 				break;
442 		}
443 
444 		/* warn that we have a new name */
445 		if (new_name && verbose > 0) {
446 			fprintf(stderr, _("Using HFS name: %s for %s\n"),
447 				ent->name,
448 				s_entry->whole_name);
449 		}
450 		/* open file */
451 		if ((hfp = hfs_open(vol, ent->name)) == 0) {
452 			sprintf(hce->error, _("can't HFS open %s"),
453 				s_entry->whole_name);
454 			return (-1);
455 		}
456 		/* if it has a data fork, then "write" it out */
457 		if (ent->u.file.dsize)
458 			write_fork(hfp, ent->u.file.dsize);
459 
460 		/* if it has a resource fork, set the fork and "write" it out */
461 		if (ent->u.file.rsize) {
462 			if ((hfs_setfork(hfp, 1)) < 0)
463 				return (-1);
464 			write_fork(hfp, ent->u.file.rsize);
465 		}
466 
467 		/* make file invisible if ISO9660 hidden */
468 		if (s_entry->de_flags & HIDDEN_FILE)
469 			ent->fdflags |= HFS_FNDR_ISINVISIBLE;
470 
471 		/* update any HFS file attributes */
472 		if ((hfs_fsetattr(hfp, ent)) < 0) {
473 			sprintf(hce->error, _("can't HFS set attributes %s"),
474 				s_entry->whole_name);
475 			return (-1);
476 		}
477 		/*
478 		 * get the ISO starting block of data fork (may be zero)
479 		 * and convert to the equivalent HFS block
480 		 */
481 		if (ent->u.file.dsize) {
482 			dext = (s_entry->starting_block - session_start) *
483 								HFS_BLK_CONV;
484 		} else {
485 			dext = 0;
486 		}
487 
488 		/*
489 		 * if the file has a resource fork (associated file),
490 		 * get it's ISO starting block and convert as above
491 		 */
492 		if (s_entry->assoc && ent->u.file.rsize) {
493 			rext =
494 			    (s_entry->assoc->starting_block - session_start) *
495 								HFS_BLK_CONV;
496 		} else {
497 			rext = 0;
498 		}
499 
500 		/* close the file and update the starting blocks */
501 		if (hfs_close(hfp, dext, rext) < 0) {
502 			sprintf(hce->error, _("can't HFS close file %s"),
503 				s_entry->whole_name);
504 			return (-1);
505 		}
506 	}
507 
508 	/* set folder info and custom icon (if it exists) */
509 	set_dir_info(vol, node);
510 
511 	/*
512 	 * process sub-directories  - have a slight problem here,
513 	 * if the directory had been relocated, then we need to find the
514 	 * real directory - we do this by first finding the
515 	 * real directory_entry, and then finding it's directory info
516 	 */
517 
518 	/* following code taken from joliet.c */
519 	for (s_entry = node->contents; s_entry; s_entry = s_entry->next) {
520 		if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0) {
521 			/*
522 			 * if the directory has been reloacted, then search the
523 			 * relocated directory for the real entry
524 			 */
525 			for (s_entry1 = reloc_dir->contents; s_entry1;
526 						s_entry1 = s_entry1->next) {
527 				if (s_entry1->parent_rec == s_entry)
528 					break;
529 			}
530 
531 			/* have a problem - can't find the real directory */
532 			if (s_entry1 == NULL) {
533 				sprintf(hce->error,
534 					_("can't locate relocated directory %s"),
535 					s_entry->whole_name);
536 				return (-1);
537 			}
538 		} else
539 			s_entry1 = s_entry;
540 
541 		/* now have the correct entry - now find the actual directory */
542 		if ((s_entry1->isorec.flags[0] & ISO_DIRECTORY) &&
543 				strcmp(s_entry1->name, ".") != 0 &&
544 				strcmp(s_entry1->name, "..") != 0) {
545 			if ((s_entry->de_flags & RELOCATED_DIRECTORY) != 0)
546 				dpnt = reloc_dir->subdir;
547 			else
548 				dpnt = node->subdir;
549 
550 			while (1) {
551 				if (dpnt->self == s_entry1)
552 					break;
553 				dpnt = dpnt->next;
554 				if (!dpnt) {
555 					sprintf(hce->error,
556 					    _("can't find directory location %s"),
557 							s_entry1->whole_name);
558 					return (-1);
559 				}
560 			}
561 			/*
562 			 * now have the correct directory
563 			 * - so do the HFS stuff
564 			 */
565 			ent = dpnt->hfs_ent;
566 
567 			/*
568 			 * if we don't have hfs entries, then this is a "deep"
569 			 * directory - this will be processed later
570 			 */
571 			if (!ent)
572 				continue;
573 
574 			/* make sub-folder */
575 			i = HFS_MAX_FLEN - strlen(ent->name);
576 			new_name = 0;
577 			tens = TEN;
578 			digits = 1;
579 
580 			while (1) {
581 				/*
582 				 * try to create new directory
583 				 * - if it exists, then append '_' to the name
584 				 * and try again
585 				 */
586 				errno = 0;
587 				if (hfs_mkdir(vol, ent->name) < 0) {
588 					if (errno != EEXIST) {
589 						/*
590 						 * not an "exist" error,
591 						 * or we can't append as the
592 						 * filename is already
593 						 * HFS_MAX_FLEN chars
594 						 */
595 						sprintf(hce->error,
596 						    _("can't HFS create folder %s"),
597 							s_entry->whole_name);
598 						return (-1);
599 					} else if (i == 0) {
600 						/*
601 						 * File name at max HFS length
602 						 * - make unique name
603 						 */
604 						if (!new_name)
605 							new_name++;
606 
607 						sprintf(ent->name +
608 						    HFS_MAX_FLEN - digits - 1,
609 						    "%s%d", LCHAR, new_name);
610 						new_name++;
611 						if (new_name == tens) {
612 							tens *= TEN;
613 							digits++;
614 						}
615 					} else {
616 						/* append '_' to get new name */
617 						strcat(ent->name, LCHAR);
618 						i--;
619 						new_name = 1;
620 					}
621 				} else
622 					break;
623 			}
624 
625 			/* warn that we have a new name */
626 			if (new_name && verbose > 0) {
627 				fprintf(stderr, _("Using HFS name: %s for %s\n"),
628 							ent->name,
629 							s_entry->whole_name);
630 			}
631 			/* see if we need to "bless" this folder */
632 			if (hfs_bless &&
633 			    strcmp(s_entry->whole_name, hfs_bless) == 0) {
634 				hfs_stat(vol, ent->name, ent);
635 				hfs_vsetbless(vol, ent->cnid);
636 				if (verbose > 0) {
637 					fprintf(stderr, _("Blessing %s (%s)\n"),
638 							ent->name,
639 							s_entry->whole_name);
640 				}
641 				/* stop any further checks */
642 				hfs_bless = NULL;
643 			}
644 			/* change to sub-folder */
645 			if (hfs_chdir(vol, ent->name) < 0)
646 				return (-1);
647 
648 			/* recursively copy files ... */
649 			ret = copy_to_mac_vol(vol, dpnt);
650 			if (ret < 0)
651 				return (ret);
652 
653 			/* change back to this folder */
654 			if (hfs_setcwd(vol, id) < 0)
655 				return (-1);
656 		}
657 	}
658 
659 	return (0);
660 }
661 
662 /*
663  *	set_dir_info:	Set directory info for a file - also use a custom
664  *			Icon - if it exists.
665  *
666  *	Sets folder' layout (window layout, view, scroll bars etc)
667  *
668  *	Set the 'HFS_FNDR_HASCUSTOMICON' bit of the folder flags
669  *	if a file called 'Icon\r' exists in the folder
670  *
671  *	Also makes sure the Icon file is invisible
672  *	Don't worry if any of this fails ...
673  *
674  *	Thanks to Rob Leslie <rob@mars.org> for how to do this.
675  */
676 
677 #define	ICON	"Icon"
678 
679 LOCAL void
set_dir_info(vol,de)680 set_dir_info(vol, de)
681 	hfsvol			*vol;
682 	struct directory	*de;
683 {
684 	hfsdirent	*ent = de->hfs_ent;
685 	hfsdirent	ent1;
686 	char		name[HFS_MAX_FLEN + 1];
687 	unsigned short	flags = 0;
688 
689 	memset(&ent1, 0, sizeof (hfsdirent));
690 
691 	sprintf(name, "%s\r", ICON);
692 
693 	/* get the attributes for the Icon file */
694 	if (hfs_stat(vol, name, &ent1) == 0) {
695 
696 		/* make sure it is invisible */
697 		ent1.fdflags |= HFS_FNDR_ISINVISIBLE;
698 
699 		/* set the new attributes for the Icon file */
700 		hfs_setattr(vol, name, &ent1);
701 
702 		/* flag the folder as having a custom icon */
703 		flags |= HFS_FNDR_HASCUSTOMICON;
704 	}
705 
706 	/* make the current folder invisible if ISO9660 hidden */
707 	if (de->self->de_flags & HIDDEN_FILE) {
708 		flags |= HFS_FNDR_ISINVISIBLE;
709 	}
710 
711 	/* may not have an hfs_ent for this directory */
712 	if (ent == NULL) {
713 		ent = &ent1;
714 		memset(ent, 0, sizeof (hfsdirent));
715 
716 		/* get the attributes for the folder */
717 		if (hfs_stat(vol, ":", ent) < 0)
718 			return;
719 	}
720 
721 	/* set HFS_FNDR_HASCUSTOMICON/HFS_FNDR_ISINVISIBLE if needed */
722 	ent->fdflags |= flags;
723 
724 	/* set the new attributes for the folder */
725 	if (hfs_setattr(vol, ":", ent) < 0) {
726 		/*
727 		 * Only needed if we add things after this if statement.
728 		 */
729 /*		return;*/
730 	}
731 }
732 
733 #endif	/* APPLE_HFS_HYB */
734