xref: /onnv-gate/usr/src/uts/common/fs/hsfs/hsfs_rrip.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright (c) 1990,1997,2000,2001 by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate  * All rights reserved.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * Rock Ridge extensions to the System Use Sharing protocol
31*0Sstevel@tonic-gate  * for the High Sierra filesystem
32*0Sstevel@tonic-gate  */
33*0Sstevel@tonic-gate 
34*0Sstevel@tonic-gate #include <sys/types.h>
35*0Sstevel@tonic-gate #include <sys/t_lock.h>
36*0Sstevel@tonic-gate #include <sys/param.h>
37*0Sstevel@tonic-gate #include <sys/systm.h>
38*0Sstevel@tonic-gate #include <sys/kmem.h>
39*0Sstevel@tonic-gate #include <sys/signal.h>
40*0Sstevel@tonic-gate #include <sys/user.h>
41*0Sstevel@tonic-gate #include <sys/proc.h>
42*0Sstevel@tonic-gate #include <sys/disp.h>
43*0Sstevel@tonic-gate #include <sys/buf.h>
44*0Sstevel@tonic-gate #include <sys/pathname.h>
45*0Sstevel@tonic-gate #include <sys/vfs.h>
46*0Sstevel@tonic-gate #include <sys/vnode.h>
47*0Sstevel@tonic-gate #include <sys/file.h>
48*0Sstevel@tonic-gate #include <sys/uio.h>
49*0Sstevel@tonic-gate #include <sys/conf.h>
50*0Sstevel@tonic-gate #include <sys/stat.h>
51*0Sstevel@tonic-gate #include <sys/mode.h>
52*0Sstevel@tonic-gate #include <sys/mkdev.h>
53*0Sstevel@tonic-gate #include <sys/ddi.h>
54*0Sstevel@tonic-gate 
55*0Sstevel@tonic-gate #include <vm/page.h>
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate #include <sys/fs/hsfs_spec.h>
58*0Sstevel@tonic-gate #include <sys/fs/hsfs_isospec.h>
59*0Sstevel@tonic-gate #include <sys/fs/hsfs_node.h>
60*0Sstevel@tonic-gate #include <sys/fs/hsfs_impl.h>
61*0Sstevel@tonic-gate #include <sys/fs/hsfs_susp.h>
62*0Sstevel@tonic-gate #include <sys/fs/hsfs_rrip.h>
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate #include <sys/statvfs.h>
65*0Sstevel@tonic-gate #include <sys/mount.h>
66*0Sstevel@tonic-gate #include <sys/swap.h>
67*0Sstevel@tonic-gate #include <sys/errno.h>
68*0Sstevel@tonic-gate #include <sys/debug.h>
69*0Sstevel@tonic-gate #include "fs/fs_subr.h"
70*0Sstevel@tonic-gate #include <sys/cmn_err.h>
71*0Sstevel@tonic-gate 
72*0Sstevel@tonic-gate static void form_time(int, uchar_t *, struct timeval *);
73*0Sstevel@tonic-gate static void name_parse(int, uchar_t *, size_t, uchar_t *, int *,
74*0Sstevel@tonic-gate     ulong_t *, int);
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate /*
77*0Sstevel@tonic-gate  *  Signature table for RRIP
78*0Sstevel@tonic-gate  */
79*0Sstevel@tonic-gate ext_signature_t  rrip_signature_table[ ] = {
80*0Sstevel@tonic-gate 	RRIP_CL,	rrip_child_link,
81*0Sstevel@tonic-gate 	RRIP_NM,	rrip_name,
82*0Sstevel@tonic-gate 	RRIP_PL,	rrip_parent_link,
83*0Sstevel@tonic-gate 	RRIP_PN,	rrip_dev_nodes,
84*0Sstevel@tonic-gate 	RRIP_PX,	rrip_file_attr,
85*0Sstevel@tonic-gate 	RRIP_RE,	rrip_reloc_dir,
86*0Sstevel@tonic-gate 	RRIP_RR,	rrip_rock_ridge,
87*0Sstevel@tonic-gate 	RRIP_SL,	rrip_sym_link,
88*0Sstevel@tonic-gate 	RRIP_TF,	rrip_file_time,
89*0Sstevel@tonic-gate 	(char *)NULL,   NULL
90*0Sstevel@tonic-gate };
91*0Sstevel@tonic-gate 
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate /*
94*0Sstevel@tonic-gate  * rrip_dev_nodes()
95*0Sstevel@tonic-gate  *
96*0Sstevel@tonic-gate  * sig_handler() for RRIP signature "PN"
97*0Sstevel@tonic-gate  *
98*0Sstevel@tonic-gate  * This function parses out the major and minor numbers from the "PN
99*0Sstevel@tonic-gate  * " SUF.
100*0Sstevel@tonic-gate  */
101*0Sstevel@tonic-gate uchar_t *
102*0Sstevel@tonic-gate rrip_dev_nodes(sig_args_t *sig_args_p)
103*0Sstevel@tonic-gate {
104*0Sstevel@tonic-gate 	uchar_t *pn_ptr = sig_args_p->SUF_ptr;
105*0Sstevel@tonic-gate 	major_t	major_dev = (major_t)RRIP_MAJOR(pn_ptr);
106*0Sstevel@tonic-gate 	minor_t	minor_dev = (minor_t)RRIP_MINOR(pn_ptr);
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate 	sig_args_p->hdp->r_dev = makedevice(major_dev, minor_dev);
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate 	return (pn_ptr + SUF_LEN(pn_ptr));
111*0Sstevel@tonic-gate }
112*0Sstevel@tonic-gate 
113*0Sstevel@tonic-gate /*
114*0Sstevel@tonic-gate  * rrip_file_attr()
115*0Sstevel@tonic-gate  *
116*0Sstevel@tonic-gate  * sig_handler() for RRIP signature "PX"
117*0Sstevel@tonic-gate  *
118*0Sstevel@tonic-gate  * This function parses out the file attributes of a file from the "PX"
119*0Sstevel@tonic-gate  * SUF.  The attributes is finds are : st_mode, st_nlink, st_uid,
120*0Sstevel@tonic-gate  * and st_gid.
121*0Sstevel@tonic-gate  */
122*0Sstevel@tonic-gate uchar_t *
123*0Sstevel@tonic-gate rrip_file_attr(sig_args_t *sig_args_p)
124*0Sstevel@tonic-gate {
125*0Sstevel@tonic-gate 	uchar_t *px_ptr = sig_args_p->SUF_ptr;
126*0Sstevel@tonic-gate 	struct hs_direntry *hdp    = sig_args_p->hdp;
127*0Sstevel@tonic-gate 
128*0Sstevel@tonic-gate 	hdp->mode  = RRIP_MODE(px_ptr);
129*0Sstevel@tonic-gate 	hdp->nlink = RRIP_NLINK(px_ptr);
130*0Sstevel@tonic-gate 	hdp->uid   = RRIP_UID(px_ptr);
131*0Sstevel@tonic-gate 	hdp->gid   = RRIP_GID(px_ptr);
132*0Sstevel@tonic-gate 
133*0Sstevel@tonic-gate 	hdp->type = IFTOVT(hdp->mode);
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate 	return (px_ptr + SUF_LEN(px_ptr));
136*0Sstevel@tonic-gate }
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate /*
139*0Sstevel@tonic-gate  * rrip_file_time()
140*0Sstevel@tonic-gate  *
141*0Sstevel@tonic-gate  * support function for rrip_file_time()
142*0Sstevel@tonic-gate  *
143*0Sstevel@tonic-gate  * This function decides whether to parse the times in a long time form
144*0Sstevel@tonic-gate  * (17 bytes) or a short time form (7 bytes).  These time formats are
145*0Sstevel@tonic-gate  * defined in the ISO 9660 specification.
146*0Sstevel@tonic-gate  */
147*0Sstevel@tonic-gate static void
148*0Sstevel@tonic-gate form_time(int time_length, uchar_t *file_time, struct timeval *tvp)
149*0Sstevel@tonic-gate {
150*0Sstevel@tonic-gate 	if (time_length == ISO_DATE_LEN)
151*0Sstevel@tonic-gate 		hs_parse_longdate(file_time, tvp);
152*0Sstevel@tonic-gate 	else
153*0Sstevel@tonic-gate 		hs_parse_dirdate(file_time, tvp);
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate }
156*0Sstevel@tonic-gate 
157*0Sstevel@tonic-gate /*
158*0Sstevel@tonic-gate  * rrip_file_time()
159*0Sstevel@tonic-gate  *
160*0Sstevel@tonic-gate  * sig_handler() for RRIP signature RRIP_TF
161*0Sstevel@tonic-gate  *
162*0Sstevel@tonic-gate  * This function parses out the file time attributes of a file from the
163*0Sstevel@tonic-gate  * "TI" SUF.  The times it parses are : st_mtime, st_atime and st_ctime.
164*0Sstevel@tonic-gate  *
165*0Sstevel@tonic-gate  * The function form_time is a support function only used in this
166*0Sstevel@tonic-gate  * function.
167*0Sstevel@tonic-gate  */
168*0Sstevel@tonic-gate uchar_t *
169*0Sstevel@tonic-gate rrip_file_time(sig_args_t *sig_args_p)
170*0Sstevel@tonic-gate {
171*0Sstevel@tonic-gate 	uchar_t *tf_ptr = sig_args_p->SUF_ptr;
172*0Sstevel@tonic-gate 
173*0Sstevel@tonic-gate 	if (IS_TIME_BIT_SET(RRIP_TF_FLAGS(tf_ptr), RRIP_TF_ACCESS_BIT)) {
174*0Sstevel@tonic-gate 		form_time(RRIP_TF_TIME_LENGTH(tf_ptr),
175*0Sstevel@tonic-gate 		    RRIP_tf_access(tf_ptr),
176*0Sstevel@tonic-gate 		    &sig_args_p->hdp->adate);
177*0Sstevel@tonic-gate 	}
178*0Sstevel@tonic-gate 
179*0Sstevel@tonic-gate 	if (IS_TIME_BIT_SET(RRIP_TF_FLAGS(tf_ptr), RRIP_TF_MODIFY_BIT)) {
180*0Sstevel@tonic-gate 		form_time(RRIP_TF_TIME_LENGTH(tf_ptr), RRIP_tf_modify(tf_ptr),
181*0Sstevel@tonic-gate 		    &sig_args_p->hdp->mdate);
182*0Sstevel@tonic-gate 	}
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate 	if (IS_TIME_BIT_SET(RRIP_TF_FLAGS(tf_ptr), RRIP_TF_ATTRIBUTES_BIT)) {
185*0Sstevel@tonic-gate 		form_time(RRIP_TF_TIME_LENGTH(tf_ptr),
186*0Sstevel@tonic-gate 		    RRIP_tf_attributes(tf_ptr),
187*0Sstevel@tonic-gate 		    &sig_args_p->hdp->cdate);
188*0Sstevel@tonic-gate 	}
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate 	return (tf_ptr + SUF_LEN(tf_ptr));
191*0Sstevel@tonic-gate }
192*0Sstevel@tonic-gate 
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate /*
196*0Sstevel@tonic-gate  * name_parse()
197*0Sstevel@tonic-gate  *
198*0Sstevel@tonic-gate  * This is a generic fuction used for sym links and filenames.  The
199*0Sstevel@tonic-gate  * flags passed to it effect the way the name/component field is parsed.
200*0Sstevel@tonic-gate  *
201*0Sstevel@tonic-gate  * The return value will be the NAME_CONTINUE or NAME_CHANGE value.
202*0Sstevel@tonic-gate  *
203*0Sstevel@tonic-gate  */
204*0Sstevel@tonic-gate static void
205*0Sstevel@tonic-gate name_parse(
206*0Sstevel@tonic-gate 	int		rrip_flags,	/* component/name flag */
207*0Sstevel@tonic-gate 	uchar_t		*SUA_string,	/* string from SUA */
208*0Sstevel@tonic-gate 	size_t		SUA_string_len, /* length of SUA string */
209*0Sstevel@tonic-gate 	uchar_t		*to_string,	/* string to copy to */
210*0Sstevel@tonic-gate 	int		*to_string_len_p, /* ptr to cur. str len */
211*0Sstevel@tonic-gate 	ulong_t		*name_flags_p,	/* internal name flags */
212*0Sstevel@tonic-gate 	int		max_name_len)	/* limit dest string to */
213*0Sstevel@tonic-gate 						/* this value */
214*0Sstevel@tonic-gate {
215*0Sstevel@tonic-gate 	size_t	tmp_name_len;
216*0Sstevel@tonic-gate 
217*0Sstevel@tonic-gate 	if (IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_ROOT)) {
218*0Sstevel@tonic-gate 		(void) strcpy((char *)to_string, "/");
219*0Sstevel@tonic-gate 		*to_string_len_p = 1;
220*0Sstevel@tonic-gate 	}
221*0Sstevel@tonic-gate 
222*0Sstevel@tonic-gate 	if (IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_CURRENT)) {
223*0Sstevel@tonic-gate 		SUA_string = (uchar_t *)".";
224*0Sstevel@tonic-gate 		SUA_string_len = 1;
225*0Sstevel@tonic-gate 	}
226*0Sstevel@tonic-gate 
227*0Sstevel@tonic-gate 	if (IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_PARENT)) {
228*0Sstevel@tonic-gate 		SUA_string = (uchar_t *)"..";
229*0Sstevel@tonic-gate 		SUA_string_len = 2;
230*0Sstevel@tonic-gate 	}
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate 	/*
233*0Sstevel@tonic-gate 	 * XXX
234*0Sstevel@tonic-gate 	 * For now, ignore the following flags and return.
235*0Sstevel@tonic-gate 	 * have to figure out how to get host name in kernel.
236*0Sstevel@tonic-gate 	 * Unsure if this even should be done.
237*0Sstevel@tonic-gate 	 */
238*0Sstevel@tonic-gate 	if (IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_VOLROOT) ||
239*0Sstevel@tonic-gate 	    IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_HOST)) {
240*0Sstevel@tonic-gate 		cmn_err(CE_NOTE,
241*0Sstevel@tonic-gate 			"VOLUME ROOT and NAME_HOST currently unsupported\n");
242*0Sstevel@tonic-gate 		return;
243*0Sstevel@tonic-gate 	}
244*0Sstevel@tonic-gate 
245*0Sstevel@tonic-gate 	/*
246*0Sstevel@tonic-gate 	 * Remember we must strncpy to the end of the curent string
247*0Sstevel@tonic-gate 	 * name because there might be something there.  Also, don't
248*0Sstevel@tonic-gate 	 * go past the max_name_len system boundry.
249*0Sstevel@tonic-gate 	 */
250*0Sstevel@tonic-gate 	tmp_name_len = strlen((char *)to_string);
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate 	SUA_string_len = (tmp_name_len + SUA_string_len) > max_name_len ?
253*0Sstevel@tonic-gate 		(max_name_len - tmp_name_len) : (SUA_string_len);
254*0Sstevel@tonic-gate 
255*0Sstevel@tonic-gate 	(void) strncpy((char *)(to_string + tmp_name_len),
256*0Sstevel@tonic-gate 		(char *)SUA_string, SUA_string_len);
257*0Sstevel@tonic-gate 
258*0Sstevel@tonic-gate 	/* NULL terminate string */
259*0Sstevel@tonic-gate 	*(to_string + tmp_name_len + SUA_string_len) = '\0';
260*0Sstevel@tonic-gate 	*(to_string_len_p) += (int)SUA_string_len;
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate 	if (IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_CONTINUE))
263*0Sstevel@tonic-gate 		SET_NAME_BIT(*(name_flags_p), RRIP_NAME_CONTINUE);
264*0Sstevel@tonic-gate 	else
265*0Sstevel@tonic-gate 		SET_NAME_BIT(*(name_flags_p), RRIP_NAME_CHANGE);
266*0Sstevel@tonic-gate 
267*0Sstevel@tonic-gate }
268*0Sstevel@tonic-gate 
269*0Sstevel@tonic-gate /*
270*0Sstevel@tonic-gate  * rrip_name()
271*0Sstevel@tonic-gate  *
272*0Sstevel@tonic-gate  * sig_handler() for RRIP signature RRIP_NM
273*0Sstevel@tonic-gate  *
274*0Sstevel@tonic-gate  * This function handles the name of the current file.  It is case
275*0Sstevel@tonic-gate  * sensitive to whatever was put into the field and does NO
276*0Sstevel@tonic-gate  * translation. It will take whatever characters were in the field.
277*0Sstevel@tonic-gate  *
278*0Sstevel@tonic-gate  * Because the flags effect the way the name is parsed the same way
279*0Sstevel@tonic-gate  * that the sym_link component parsing is done, we will use the same
280*0Sstevel@tonic-gate  * function to do the actual parsing.
281*0Sstevel@tonic-gate  */
282*0Sstevel@tonic-gate uchar_t  *
283*0Sstevel@tonic-gate rrip_name(sig_args_t *sig_args_p)
284*0Sstevel@tonic-gate {
285*0Sstevel@tonic-gate 	uchar_t *nm_ptr = sig_args_p->SUF_ptr;
286*0Sstevel@tonic-gate 
287*0Sstevel@tonic-gate 	if ((sig_args_p->name_p == (uchar_t *)NULL) ||
288*0Sstevel@tonic-gate 	    (sig_args_p->name_len_p == (int *)NULL))
289*0Sstevel@tonic-gate 		goto end;
290*0Sstevel@tonic-gate 	/*
291*0Sstevel@tonic-gate 	 * If we have a "." or ".." directory, we should not look for
292*0Sstevel@tonic-gate 	 * an alternate name
293*0Sstevel@tonic-gate 	 */
294*0Sstevel@tonic-gate 	if (HDE_NAME_LEN(sig_args_p->dirp) == 1) {
295*0Sstevel@tonic-gate 		if (*((char *)HDE_name(sig_args_p->dirp)) == '\0') {
296*0Sstevel@tonic-gate 			(void) strcpy((char *)sig_args_p->name_p, ".");
297*0Sstevel@tonic-gate 			*sig_args_p->name_len_p = 1;
298*0Sstevel@tonic-gate 			goto end;
299*0Sstevel@tonic-gate 		} else if (*((char *)HDE_name(sig_args_p->dirp)) == '\1') {
300*0Sstevel@tonic-gate 			(void) strcpy((char *)sig_args_p->name_p, "..");
301*0Sstevel@tonic-gate 			*sig_args_p->name_len_p = 2;
302*0Sstevel@tonic-gate 			goto end;
303*0Sstevel@tonic-gate 		}
304*0Sstevel@tonic-gate 	}
305*0Sstevel@tonic-gate 
306*0Sstevel@tonic-gate 	name_parse((int)RRIP_NAME_FLAGS(nm_ptr), RRIP_name(nm_ptr),
307*0Sstevel@tonic-gate 	    (size_t)RRIP_NAME_LEN(nm_ptr), sig_args_p->name_p,
308*0Sstevel@tonic-gate 	    sig_args_p->name_len_p, &(sig_args_p->name_flags),
309*0Sstevel@tonic-gate 	    MAXNAMELEN);
310*0Sstevel@tonic-gate 
311*0Sstevel@tonic-gate end:
312*0Sstevel@tonic-gate 	return (nm_ptr + SUF_LEN(nm_ptr));
313*0Sstevel@tonic-gate }
314*0Sstevel@tonic-gate 
315*0Sstevel@tonic-gate 
316*0Sstevel@tonic-gate /*
317*0Sstevel@tonic-gate  * rrip_sym_link()
318*0Sstevel@tonic-gate  *
319*0Sstevel@tonic-gate  * sig_handler() for RRIP signature RRIP_SL
320*0Sstevel@tonic-gate  *
321*0Sstevel@tonic-gate  * creates a symlink buffer to simulate sym_links.
322*0Sstevel@tonic-gate  */
323*0Sstevel@tonic-gate uchar_t *
324*0Sstevel@tonic-gate rrip_sym_link(sig_args_t *sig_args_p)
325*0Sstevel@tonic-gate {
326*0Sstevel@tonic-gate 	uchar_t	*sl_ptr = sig_args_p->SUF_ptr;
327*0Sstevel@tonic-gate 	uchar_t	*comp_ptr;
328*0Sstevel@tonic-gate 	char 	*tmp_sym_link;
329*0Sstevel@tonic-gate 	struct hs_direntry *hdp = sig_args_p->hdp;
330*0Sstevel@tonic-gate 	int	sym_link_len;
331*0Sstevel@tonic-gate 	char	*sym_link;
332*0Sstevel@tonic-gate 
333*0Sstevel@tonic-gate 	if (hdp->type != VLNK)
334*0Sstevel@tonic-gate 		goto end;
335*0Sstevel@tonic-gate 
336*0Sstevel@tonic-gate 	/*
337*0Sstevel@tonic-gate 	 * If the sym link has already been created, don't recreate it
338*0Sstevel@tonic-gate 	 */
339*0Sstevel@tonic-gate 	if (IS_NAME_BIT_SET(sig_args_p->name_flags, RRIP_SYM_LINK_COMPLETE))
340*0Sstevel@tonic-gate 		goto end;
341*0Sstevel@tonic-gate 
342*0Sstevel@tonic-gate 	sym_link = kmem_alloc(MAXPATHLEN + 1, KM_SLEEP);
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate 	/*
345*0Sstevel@tonic-gate 	 * If there is an original string put it into sym_link[], otherwise
346*0Sstevel@tonic-gate 	 * initialize sym_link[] to the empty string.
347*0Sstevel@tonic-gate 	 */
348*0Sstevel@tonic-gate 	if (hdp->sym_link != (char *)NULL) {
349*0Sstevel@tonic-gate 		sym_link_len = (int)strlen(strcpy(sym_link, hdp->sym_link));
350*0Sstevel@tonic-gate 	} else {
351*0Sstevel@tonic-gate 		sym_link[0] = '\0';
352*0Sstevel@tonic-gate 		sym_link_len = 0;
353*0Sstevel@tonic-gate 	}
354*0Sstevel@tonic-gate 
355*0Sstevel@tonic-gate 	/* for all components */
356*0Sstevel@tonic-gate 	for (comp_ptr = RRIP_sl_comp(sl_ptr);
357*0Sstevel@tonic-gate 		comp_ptr < (sl_ptr + SUF_LEN(sl_ptr));
358*0Sstevel@tonic-gate 		comp_ptr += RRIP_COMP_LEN(comp_ptr)) {
359*0Sstevel@tonic-gate 
360*0Sstevel@tonic-gate 		name_parse((int)RRIP_COMP_FLAGS(comp_ptr),
361*0Sstevel@tonic-gate 		    RRIP_comp(comp_ptr),
362*0Sstevel@tonic-gate 		    (size_t)RRIP_COMP_NAME_LEN(comp_ptr), (uchar_t *)sym_link,
363*0Sstevel@tonic-gate 		    &sym_link_len, &(sig_args_p->name_flags),
364*0Sstevel@tonic-gate 		    MAXPATHLEN);
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate 		/*
367*0Sstevel@tonic-gate 		 * If the component is continued, Don't put a
368*0Sstevel@tonic-gate 		 * '/' in the pathname, but do NULL terminate it.
369*0Sstevel@tonic-gate 		 * And avoid 2 '//' in a row, or if '/' was wanted
370*0Sstevel@tonic-gate 		 */
371*0Sstevel@tonic-gate 		if (IS_NAME_BIT_SET(RRIP_COMP_FLAGS(comp_ptr),
372*0Sstevel@tonic-gate 				    RRIP_NAME_CONTINUE) ||
373*0Sstevel@tonic-gate 		    (sym_link[sym_link_len - 1] == '/')) {
374*0Sstevel@tonic-gate 
375*0Sstevel@tonic-gate 			sym_link[sym_link_len] = '\0';
376*0Sstevel@tonic-gate 		} else {
377*0Sstevel@tonic-gate 			sym_link[sym_link_len] = '/';
378*0Sstevel@tonic-gate 			sym_link[sym_link_len + 1] = '\0';
379*0Sstevel@tonic-gate 
380*0Sstevel@tonic-gate 			/* add 1 to sym_link_len for '/' */
381*0Sstevel@tonic-gate 			sym_link_len++;
382*0Sstevel@tonic-gate 		}
383*0Sstevel@tonic-gate 
384*0Sstevel@tonic-gate 	}
385*0Sstevel@tonic-gate 
386*0Sstevel@tonic-gate 	/*
387*0Sstevel@tonic-gate 	 * take out  the last slash
388*0Sstevel@tonic-gate 	 */
389*0Sstevel@tonic-gate 	if (sym_link[sym_link_len - 1] == '/')
390*0Sstevel@tonic-gate 		sym_link[--sym_link_len] = '\0';
391*0Sstevel@tonic-gate 
392*0Sstevel@tonic-gate 	/*
393*0Sstevel@tonic-gate 	 * if no memory has been allocated, get some, otherwise, append
394*0Sstevel@tonic-gate 	 * to the current allocation
395*0Sstevel@tonic-gate 	 */
396*0Sstevel@tonic-gate 
397*0Sstevel@tonic-gate 	tmp_sym_link = kmem_alloc(SYM_LINK_LEN(sym_link), KM_SLEEP);
398*0Sstevel@tonic-gate 
399*0Sstevel@tonic-gate 	(void) strcpy(tmp_sym_link, sym_link);
400*0Sstevel@tonic-gate 
401*0Sstevel@tonic-gate 	if (hdp->sym_link != (char *)NULL)
402*0Sstevel@tonic-gate 		kmem_free(hdp->sym_link, (size_t)(hdp->ext_size + 1));
403*0Sstevel@tonic-gate 
404*0Sstevel@tonic-gate 	hdp->sym_link = (char *)&tmp_sym_link[0];
405*0Sstevel@tonic-gate 	/* the size of a symlink is its length */
406*0Sstevel@tonic-gate 	hdp->ext_size = (uint_t)strlen(tmp_sym_link);
407*0Sstevel@tonic-gate 
408*0Sstevel@tonic-gate 	if (!IS_NAME_BIT_SET(RRIP_SL_FLAGS(sl_ptr), RRIP_NAME_CONTINUE)) {
409*0Sstevel@tonic-gate 		/* reached the end of the symbolic link */
410*0Sstevel@tonic-gate 		SET_NAME_BIT(sig_args_p->name_flags, RRIP_SYM_LINK_COMPLETE);
411*0Sstevel@tonic-gate 	}
412*0Sstevel@tonic-gate 
413*0Sstevel@tonic-gate 	kmem_free(sym_link, MAXPATHLEN + 1);
414*0Sstevel@tonic-gate end:
415*0Sstevel@tonic-gate 	return (sl_ptr + SUF_LEN(sl_ptr));
416*0Sstevel@tonic-gate }
417*0Sstevel@tonic-gate 
418*0Sstevel@tonic-gate /*
419*0Sstevel@tonic-gate  * rrip_namecopy()
420*0Sstevel@tonic-gate  *
421*0Sstevel@tonic-gate  * This function will copy the rrip name to the "to" buffer, if it
422*0Sstevel@tonic-gate  * exists.
423*0Sstevel@tonic-gate  *
424*0Sstevel@tonic-gate  * XXX -  We should speed this up by implementing the search in
425*0Sstevel@tonic-gate  * parse_sua().  It works right now, so I don't want to mess with it.
426*0Sstevel@tonic-gate  */
427*0Sstevel@tonic-gate int
428*0Sstevel@tonic-gate rrip_namecopy(
429*0Sstevel@tonic-gate 	char 	*from,			/* name to copy */
430*0Sstevel@tonic-gate 	char 	*to,			/* string to copy "from" to */
431*0Sstevel@tonic-gate 	char  	*tmp_name,		/* temp storage for original name */
432*0Sstevel@tonic-gate 	uchar_t	*dirp,			/* directory entry pointer */
433*0Sstevel@tonic-gate 	struct 	hsfs *fsp,		/* filesystem pointer */
434*0Sstevel@tonic-gate 	struct 	hs_direntry *hdp)	/* directory entry pointer to put */
435*0Sstevel@tonic-gate 					/* all that good info in */
436*0Sstevel@tonic-gate {
437*0Sstevel@tonic-gate 	int	size = 0;
438*0Sstevel@tonic-gate 	int	change_flag = 0;
439*0Sstevel@tonic-gate 	int	ret_val;
440*0Sstevel@tonic-gate 
441*0Sstevel@tonic-gate 	if ((to == (char *)NULL) ||
442*0Sstevel@tonic-gate 	    (from == (char *)NULL) ||
443*0Sstevel@tonic-gate 	    (dirp == (uchar_t *)NULL)) {
444*0Sstevel@tonic-gate 		return (0);
445*0Sstevel@tonic-gate 	}
446*0Sstevel@tonic-gate 
447*0Sstevel@tonic-gate 	/* special handling for '.' and '..' */
448*0Sstevel@tonic-gate 
449*0Sstevel@tonic-gate 	if (HDE_NAME_LEN(dirp) == 1) {
450*0Sstevel@tonic-gate 		if (*((char *)HDE_name(dirp)) == '\0') {
451*0Sstevel@tonic-gate 			(void) strcpy(to, ".");
452*0Sstevel@tonic-gate 			return (1);
453*0Sstevel@tonic-gate 		} else if (*((char *)HDE_name(dirp)) == '\1') {
454*0Sstevel@tonic-gate 			(void) strcpy(to, "..");
455*0Sstevel@tonic-gate 			return (2);
456*0Sstevel@tonic-gate 		}
457*0Sstevel@tonic-gate 	}
458*0Sstevel@tonic-gate 
459*0Sstevel@tonic-gate 
460*0Sstevel@tonic-gate 	ret_val = parse_sua((uchar_t *)to, &size, &change_flag, dirp,
461*0Sstevel@tonic-gate 			hdp, fsp, (uchar_t *)NULL, NULL);
462*0Sstevel@tonic-gate 
463*0Sstevel@tonic-gate 	if (IS_NAME_BIT_SET(change_flag, RRIP_NAME_CHANGE) && !ret_val)
464*0Sstevel@tonic-gate 		return (size);
465*0Sstevel@tonic-gate 
466*0Sstevel@tonic-gate 	/*
467*0Sstevel@tonic-gate 	 * Well, the name was not found
468*0Sstevel@tonic-gate 	 *
469*0Sstevel@tonic-gate 	 * make rripname an upper case "nm" (to), so that
470*0Sstevel@tonic-gate 	 * we can compare it the current HDE_DIR_NAME()
471*0Sstevel@tonic-gate 	 * without nuking the original "nm", for future case
472*0Sstevel@tonic-gate 	 * sensitive name comparing
473*0Sstevel@tonic-gate 	 */
474*0Sstevel@tonic-gate 	(void) strcpy(tmp_name, from);		/* keep original */
475*0Sstevel@tonic-gate 	size = hs_uppercase_copy(tmp_name, from, (int)strlen(from));
476*0Sstevel@tonic-gate 
477*0Sstevel@tonic-gate 	return (-1);
478*0Sstevel@tonic-gate }
479*0Sstevel@tonic-gate 
480*0Sstevel@tonic-gate 
481*0Sstevel@tonic-gate 
482*0Sstevel@tonic-gate /*
483*0Sstevel@tonic-gate  * rrip_reloc_dir()
484*0Sstevel@tonic-gate  *
485*0Sstevel@tonic-gate  * This function is fairly bogus.  All it does is cause a failure of
486*0Sstevel@tonic-gate  * the hs_parsedir, so that no vnode will be made for it and
487*0Sstevel@tonic-gate  * essentially, the directory will no longer be seen.  This is part
488*0Sstevel@tonic-gate  * of the directory hierarchy mess, where the relocated directory will
489*0Sstevel@tonic-gate  * be hidden as far as ISO 9660 is concerned.  When we hit the child
490*0Sstevel@tonic-gate  * link "CL" SUF, then we will read the new directory.
491*0Sstevel@tonic-gate  */
492*0Sstevel@tonic-gate uchar_t *
493*0Sstevel@tonic-gate rrip_reloc_dir(sig_args_t *sig_args_p)
494*0Sstevel@tonic-gate {
495*0Sstevel@tonic-gate 	uchar_t *re_ptr = sig_args_p->SUF_ptr;
496*0Sstevel@tonic-gate 
497*0Sstevel@tonic-gate 	sig_args_p->flags = RELOC_DIR;
498*0Sstevel@tonic-gate 
499*0Sstevel@tonic-gate 	return (re_ptr + SUF_LEN(re_ptr));
500*0Sstevel@tonic-gate }
501*0Sstevel@tonic-gate 
502*0Sstevel@tonic-gate 
503*0Sstevel@tonic-gate 
504*0Sstevel@tonic-gate /*
505*0Sstevel@tonic-gate  * rrip_child_link()
506*0Sstevel@tonic-gate  *
507*0Sstevel@tonic-gate  * This is the child link part of the directory hierarchy stuff and
508*0Sstevel@tonic-gate  * this does not really do much anyway.  All it does is read the
509*0Sstevel@tonic-gate  * directory entry that the child link SUF contains.  All should be
510*0Sstevel@tonic-gate  * fine then.
511*0Sstevel@tonic-gate  */
512*0Sstevel@tonic-gate uchar_t *
513*0Sstevel@tonic-gate rrip_child_link(sig_args_t *sig_args_p)
514*0Sstevel@tonic-gate {
515*0Sstevel@tonic-gate 	uchar_t *cl_ptr = sig_args_p->SUF_ptr;
516*0Sstevel@tonic-gate 
517*0Sstevel@tonic-gate 	sig_args_p->hdp->ext_lbn = RRIP_CHILD_LBN(cl_ptr);
518*0Sstevel@tonic-gate 
519*0Sstevel@tonic-gate 	hs_filldirent(sig_args_p->fsp->hsfs_rootvp, sig_args_p->hdp);
520*0Sstevel@tonic-gate 
521*0Sstevel@tonic-gate 	sig_args_p->flags = 0;
522*0Sstevel@tonic-gate 
523*0Sstevel@tonic-gate 	return (cl_ptr + SUF_LEN(cl_ptr));
524*0Sstevel@tonic-gate }
525*0Sstevel@tonic-gate 
526*0Sstevel@tonic-gate 
527*0Sstevel@tonic-gate /*
528*0Sstevel@tonic-gate  * rrip_parent_link()
529*0Sstevel@tonic-gate  *
530*0Sstevel@tonic-gate  * This is the parent link part of the directory hierarchy stuff and
531*0Sstevel@tonic-gate  * this does not really do much anyway.  All it does is read the
532*0Sstevel@tonic-gate  * directory entry that the parent link SUF contains.  All should be
533*0Sstevel@tonic-gate  * fine then.
534*0Sstevel@tonic-gate  */
535*0Sstevel@tonic-gate uchar_t *
536*0Sstevel@tonic-gate rrip_parent_link(sig_args_t *sig_args_p)
537*0Sstevel@tonic-gate {
538*0Sstevel@tonic-gate 	uchar_t *pl_ptr = sig_args_p->SUF_ptr;
539*0Sstevel@tonic-gate 
540*0Sstevel@tonic-gate 	sig_args_p->hdp->ext_lbn = RRIP_PARENT_LBN(pl_ptr);
541*0Sstevel@tonic-gate 
542*0Sstevel@tonic-gate 	hs_filldirent(sig_args_p->fsp->hsfs_rootvp, sig_args_p->hdp);
543*0Sstevel@tonic-gate 
544*0Sstevel@tonic-gate 	sig_args_p->flags = 0;
545*0Sstevel@tonic-gate 
546*0Sstevel@tonic-gate 	return (pl_ptr + SUF_LEN(pl_ptr));
547*0Sstevel@tonic-gate }
548*0Sstevel@tonic-gate 
549*0Sstevel@tonic-gate 
550*0Sstevel@tonic-gate /*
551*0Sstevel@tonic-gate  * rrip_rock_ridge()
552*0Sstevel@tonic-gate  *
553*0Sstevel@tonic-gate  * This function is supposed to aid in speed of the filesystem.
554*0Sstevel@tonic-gate  *
555*0Sstevel@tonic-gate  * XXX - It is only here as a place holder so far.
556*0Sstevel@tonic-gate  */
557*0Sstevel@tonic-gate uchar_t *
558*0Sstevel@tonic-gate rrip_rock_ridge(sig_args_t *sig_args_p)
559*0Sstevel@tonic-gate {
560*0Sstevel@tonic-gate 	uchar_t *rr_ptr = sig_args_p->SUF_ptr;
561*0Sstevel@tonic-gate 
562*0Sstevel@tonic-gate 	return (rr_ptr + SUF_LEN(rr_ptr));
563*0Sstevel@tonic-gate }
564