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