17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 554e0249cSfrankho * Common Development and Distribution License (the "License"). 654e0249cSfrankho * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*2daa2183Sbatschul * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23cf83459aSfrankho * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * Rock Ridge extensions to the System Use Sharing protocol 287c478bd9Sstevel@tonic-gate * for the High Sierra filesystem 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #include <sys/types.h> 327c478bd9Sstevel@tonic-gate #include <sys/t_lock.h> 337c478bd9Sstevel@tonic-gate #include <sys/param.h> 347c478bd9Sstevel@tonic-gate #include <sys/systm.h> 357c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 367c478bd9Sstevel@tonic-gate #include <sys/signal.h> 377c478bd9Sstevel@tonic-gate #include <sys/user.h> 387c478bd9Sstevel@tonic-gate #include <sys/proc.h> 397c478bd9Sstevel@tonic-gate #include <sys/disp.h> 407c478bd9Sstevel@tonic-gate #include <sys/buf.h> 417c478bd9Sstevel@tonic-gate #include <sys/pathname.h> 427c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 437c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 447c478bd9Sstevel@tonic-gate #include <sys/file.h> 457c478bd9Sstevel@tonic-gate #include <sys/uio.h> 467c478bd9Sstevel@tonic-gate #include <sys/conf.h> 477c478bd9Sstevel@tonic-gate #include <sys/stat.h> 487c478bd9Sstevel@tonic-gate #include <sys/mode.h> 497c478bd9Sstevel@tonic-gate #include <sys/mkdev.h> 507c478bd9Sstevel@tonic-gate #include <sys/ddi.h> 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate #include <vm/page.h> 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_spec.h> 557c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_isospec.h> 567c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_node.h> 577c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_impl.h> 587c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_susp.h> 597c478bd9Sstevel@tonic-gate #include <sys/fs/hsfs_rrip.h> 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate #include <sys/statvfs.h> 627c478bd9Sstevel@tonic-gate #include <sys/mount.h> 637c478bd9Sstevel@tonic-gate #include <sys/swap.h> 647c478bd9Sstevel@tonic-gate #include <sys/errno.h> 657c478bd9Sstevel@tonic-gate #include <sys/debug.h> 667c478bd9Sstevel@tonic-gate #include "fs/fs_subr.h" 677c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate static void form_time(int, uchar_t *, struct timeval *); 707c478bd9Sstevel@tonic-gate static void name_parse(int, uchar_t *, size_t, uchar_t *, int *, 717c478bd9Sstevel@tonic-gate ulong_t *, int); 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate /* 747c478bd9Sstevel@tonic-gate * Signature table for RRIP 757c478bd9Sstevel@tonic-gate */ 767c478bd9Sstevel@tonic-gate ext_signature_t rrip_signature_table[ ] = { 777c478bd9Sstevel@tonic-gate RRIP_CL, rrip_child_link, 787c478bd9Sstevel@tonic-gate RRIP_NM, rrip_name, 797c478bd9Sstevel@tonic-gate RRIP_PL, rrip_parent_link, 807c478bd9Sstevel@tonic-gate RRIP_PN, rrip_dev_nodes, 817c478bd9Sstevel@tonic-gate RRIP_PX, rrip_file_attr, 827c478bd9Sstevel@tonic-gate RRIP_RE, rrip_reloc_dir, 837c478bd9Sstevel@tonic-gate RRIP_RR, rrip_rock_ridge, 847c478bd9Sstevel@tonic-gate RRIP_SL, rrip_sym_link, 857c478bd9Sstevel@tonic-gate RRIP_TF, rrip_file_time, 867c478bd9Sstevel@tonic-gate (char *)NULL, NULL 877c478bd9Sstevel@tonic-gate }; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate /* 917c478bd9Sstevel@tonic-gate * rrip_dev_nodes() 927c478bd9Sstevel@tonic-gate * 937c478bd9Sstevel@tonic-gate * sig_handler() for RRIP signature "PN" 947c478bd9Sstevel@tonic-gate * 957c478bd9Sstevel@tonic-gate * This function parses out the major and minor numbers from the "PN 967c478bd9Sstevel@tonic-gate * " SUF. 977c478bd9Sstevel@tonic-gate */ 987c478bd9Sstevel@tonic-gate uchar_t * 997c478bd9Sstevel@tonic-gate rrip_dev_nodes(sig_args_t *sig_args_p) 1007c478bd9Sstevel@tonic-gate { 1017c478bd9Sstevel@tonic-gate uchar_t *pn_ptr = sig_args_p->SUF_ptr; 1027c478bd9Sstevel@tonic-gate major_t major_dev = (major_t)RRIP_MAJOR(pn_ptr); 1037c478bd9Sstevel@tonic-gate minor_t minor_dev = (minor_t)RRIP_MINOR(pn_ptr); 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate sig_args_p->hdp->r_dev = makedevice(major_dev, minor_dev); 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate return (pn_ptr + SUF_LEN(pn_ptr)); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate /* 1117c478bd9Sstevel@tonic-gate * rrip_file_attr() 1127c478bd9Sstevel@tonic-gate * 1137c478bd9Sstevel@tonic-gate * sig_handler() for RRIP signature "PX" 1147c478bd9Sstevel@tonic-gate * 1157c478bd9Sstevel@tonic-gate * This function parses out the file attributes of a file from the "PX" 1167c478bd9Sstevel@tonic-gate * SUF. The attributes is finds are : st_mode, st_nlink, st_uid, 1177c478bd9Sstevel@tonic-gate * and st_gid. 1187c478bd9Sstevel@tonic-gate */ 1197c478bd9Sstevel@tonic-gate uchar_t * 1207c478bd9Sstevel@tonic-gate rrip_file_attr(sig_args_t *sig_args_p) 1217c478bd9Sstevel@tonic-gate { 1227c478bd9Sstevel@tonic-gate uchar_t *px_ptr = sig_args_p->SUF_ptr; 1237c478bd9Sstevel@tonic-gate struct hs_direntry *hdp = sig_args_p->hdp; 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate hdp->mode = RRIP_MODE(px_ptr); 1267c478bd9Sstevel@tonic-gate hdp->nlink = RRIP_NLINK(px_ptr); 1277c478bd9Sstevel@tonic-gate hdp->uid = RRIP_UID(px_ptr); 1287c478bd9Sstevel@tonic-gate hdp->gid = RRIP_GID(px_ptr); 1297c478bd9Sstevel@tonic-gate 130d10b6702Sfrankho if (SUF_LEN(px_ptr) >= RRIP_PX_SIZE) 131d10b6702Sfrankho hdp->inode = (ino64_t)RRIP_INO(px_ptr); 132d10b6702Sfrankho else 133d10b6702Sfrankho hdp->inode = 0; 134d10b6702Sfrankho 1357c478bd9Sstevel@tonic-gate hdp->type = IFTOVT(hdp->mode); 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate return (px_ptr + SUF_LEN(px_ptr)); 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate /* 1417c478bd9Sstevel@tonic-gate * rrip_file_time() 1427c478bd9Sstevel@tonic-gate * 1437c478bd9Sstevel@tonic-gate * support function for rrip_file_time() 1447c478bd9Sstevel@tonic-gate * 1457c478bd9Sstevel@tonic-gate * This function decides whether to parse the times in a long time form 1467c478bd9Sstevel@tonic-gate * (17 bytes) or a short time form (7 bytes). These time formats are 1477c478bd9Sstevel@tonic-gate * defined in the ISO 9660 specification. 1487c478bd9Sstevel@tonic-gate */ 1497c478bd9Sstevel@tonic-gate static void 1507c478bd9Sstevel@tonic-gate form_time(int time_length, uchar_t *file_time, struct timeval *tvp) 1517c478bd9Sstevel@tonic-gate { 1527c478bd9Sstevel@tonic-gate if (time_length == ISO_DATE_LEN) 1537c478bd9Sstevel@tonic-gate hs_parse_longdate(file_time, tvp); 1547c478bd9Sstevel@tonic-gate else 1557c478bd9Sstevel@tonic-gate hs_parse_dirdate(file_time, tvp); 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate /* 1607c478bd9Sstevel@tonic-gate * rrip_file_time() 1617c478bd9Sstevel@tonic-gate * 1627c478bd9Sstevel@tonic-gate * sig_handler() for RRIP signature RRIP_TF 1637c478bd9Sstevel@tonic-gate * 1647c478bd9Sstevel@tonic-gate * This function parses out the file time attributes of a file from the 1657c478bd9Sstevel@tonic-gate * "TI" SUF. The times it parses are : st_mtime, st_atime and st_ctime. 1667c478bd9Sstevel@tonic-gate * 1677c478bd9Sstevel@tonic-gate * The function form_time is a support function only used in this 1687c478bd9Sstevel@tonic-gate * function. 1697c478bd9Sstevel@tonic-gate */ 1707c478bd9Sstevel@tonic-gate uchar_t * 1717c478bd9Sstevel@tonic-gate rrip_file_time(sig_args_t *sig_args_p) 1727c478bd9Sstevel@tonic-gate { 1737c478bd9Sstevel@tonic-gate uchar_t *tf_ptr = sig_args_p->SUF_ptr; 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate if (IS_TIME_BIT_SET(RRIP_TF_FLAGS(tf_ptr), RRIP_TF_ACCESS_BIT)) { 1767c478bd9Sstevel@tonic-gate form_time(RRIP_TF_TIME_LENGTH(tf_ptr), 1777c478bd9Sstevel@tonic-gate RRIP_tf_access(tf_ptr), 1787c478bd9Sstevel@tonic-gate &sig_args_p->hdp->adate); 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate if (IS_TIME_BIT_SET(RRIP_TF_FLAGS(tf_ptr), RRIP_TF_MODIFY_BIT)) { 1827c478bd9Sstevel@tonic-gate form_time(RRIP_TF_TIME_LENGTH(tf_ptr), RRIP_tf_modify(tf_ptr), 1837c478bd9Sstevel@tonic-gate &sig_args_p->hdp->mdate); 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate if (IS_TIME_BIT_SET(RRIP_TF_FLAGS(tf_ptr), RRIP_TF_ATTRIBUTES_BIT)) { 1877c478bd9Sstevel@tonic-gate form_time(RRIP_TF_TIME_LENGTH(tf_ptr), 1887c478bd9Sstevel@tonic-gate RRIP_tf_attributes(tf_ptr), 1897c478bd9Sstevel@tonic-gate &sig_args_p->hdp->cdate); 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate return (tf_ptr + SUF_LEN(tf_ptr)); 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate /* 1987c478bd9Sstevel@tonic-gate * name_parse() 1997c478bd9Sstevel@tonic-gate * 2007c478bd9Sstevel@tonic-gate * This is a generic fuction used for sym links and filenames. The 2017c478bd9Sstevel@tonic-gate * flags passed to it effect the way the name/component field is parsed. 2027c478bd9Sstevel@tonic-gate * 2037c478bd9Sstevel@tonic-gate * The return value will be the NAME_CONTINUE or NAME_CHANGE value. 2047c478bd9Sstevel@tonic-gate * 2057c478bd9Sstevel@tonic-gate */ 2067c478bd9Sstevel@tonic-gate static void 2077c478bd9Sstevel@tonic-gate name_parse( 2087c478bd9Sstevel@tonic-gate int rrip_flags, /* component/name flag */ 2097c478bd9Sstevel@tonic-gate uchar_t *SUA_string, /* string from SUA */ 2107c478bd9Sstevel@tonic-gate size_t SUA_string_len, /* length of SUA string */ 211cf83459aSfrankho uchar_t *dst, /* string to copy to */ 212cf83459aSfrankho int *dst_lenp, /* ptr to cur. str len */ 2137c478bd9Sstevel@tonic-gate ulong_t *name_flags_p, /* internal name flags */ 214cf83459aSfrankho int dst_size) /* limit dest string to */ 2157c478bd9Sstevel@tonic-gate /* this value */ 2167c478bd9Sstevel@tonic-gate { 217d10b6702Sfrankho size_t off; 218d10b6702Sfrankho size_t len; 219d10b6702Sfrankho 220cf83459aSfrankho if (IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_ROOT)) 221*2daa2183Sbatschul dst[0] = 0; 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate if (IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_CURRENT)) { 2247c478bd9Sstevel@tonic-gate SUA_string = (uchar_t *)"."; 2257c478bd9Sstevel@tonic-gate SUA_string_len = 1; 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate if (IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_PARENT)) { 2297c478bd9Sstevel@tonic-gate SUA_string = (uchar_t *)".."; 2307c478bd9Sstevel@tonic-gate SUA_string_len = 2; 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate /* 2347c478bd9Sstevel@tonic-gate * XXX 2357c478bd9Sstevel@tonic-gate * For now, ignore the following flags and return. 2367c478bd9Sstevel@tonic-gate * have to figure out how to get host name in kernel. 2377c478bd9Sstevel@tonic-gate * Unsure if this even should be done. 2387c478bd9Sstevel@tonic-gate */ 2397c478bd9Sstevel@tonic-gate if (IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_VOLROOT) || 2407c478bd9Sstevel@tonic-gate IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_HOST)) { 2417c478bd9Sstevel@tonic-gate cmn_err(CE_NOTE, 2427c478bd9Sstevel@tonic-gate "VOLUME ROOT and NAME_HOST currently unsupported\n"); 2437c478bd9Sstevel@tonic-gate return; 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate /* 24754e0249cSfrankho * strlcat() has two nice properties: 24854e0249cSfrankho * - the size of the output buffer includes the trailing '\0' 24954e0249cSfrankho * - we pass "total size" not "remaining size" 25054e0249cSfrankho * It'd be the ideal candidate for this codeblock - make it: 25154e0249cSfrankho * 25254e0249cSfrankho * strlcat(dst, SUA_string, 25354e0249cSfrankho * MIN(dstsize, strlen(dst) + SUA_string_len + 1)); 25454e0249cSfrankho * 25554e0249cSfrankho * Unfortunately, strlcat() cannot deal with input strings 25654e0249cSfrankho * that are not NULL-terminated - like SUA_string can be in 25754e0249cSfrankho * our case here. So we can't use it :( 258d10b6702Sfrankho * Now strncat() doesn't work either - because it doesn't deal 259d10b6702Sfrankho * with strings for which the 'potential NULL-termination' isn't 260d10b6702Sfrankho * accessible - strncat(dst, NULL, 0) crashes although it copies 261d10b6702Sfrankho * nothing in any case. If the SUA ends on a mapping boundary, 262d10b6702Sfrankho * then telling strncat() to copy no more than the remaining bytes 263d10b6702Sfrankho * in the buffer is of no avail if there's no NULL byte in them. 264d10b6702Sfrankho * 265d10b6702Sfrankho * Hence - binary copy. What are all these str* funcs for ?? 2667c478bd9Sstevel@tonic-gate */ 26754e0249cSfrankho dst_size--; /* trailing '\0' */ 26854e0249cSfrankho 269d10b6702Sfrankho off = strlen((char *)dst); 270d10b6702Sfrankho len = MIN(dst_size - off, SUA_string_len); 271d10b6702Sfrankho bcopy((char *)SUA_string, (char *)(dst + off), len); 272d10b6702Sfrankho dst[off + len] = '\0'; 27354e0249cSfrankho *dst_lenp = strlen((char *)dst); 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate if (IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_CONTINUE)) 2767c478bd9Sstevel@tonic-gate SET_NAME_BIT(*(name_flags_p), RRIP_NAME_CONTINUE); 2777c478bd9Sstevel@tonic-gate else 2787c478bd9Sstevel@tonic-gate SET_NAME_BIT(*(name_flags_p), RRIP_NAME_CHANGE); 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate /* 2837c478bd9Sstevel@tonic-gate * rrip_name() 2847c478bd9Sstevel@tonic-gate * 2857c478bd9Sstevel@tonic-gate * sig_handler() for RRIP signature RRIP_NM 2867c478bd9Sstevel@tonic-gate * 2877c478bd9Sstevel@tonic-gate * This function handles the name of the current file. It is case 2887c478bd9Sstevel@tonic-gate * sensitive to whatever was put into the field and does NO 2897c478bd9Sstevel@tonic-gate * translation. It will take whatever characters were in the field. 2907c478bd9Sstevel@tonic-gate * 2917c478bd9Sstevel@tonic-gate * Because the flags effect the way the name is parsed the same way 2927c478bd9Sstevel@tonic-gate * that the sym_link component parsing is done, we will use the same 2937c478bd9Sstevel@tonic-gate * function to do the actual parsing. 2947c478bd9Sstevel@tonic-gate */ 2957c478bd9Sstevel@tonic-gate uchar_t * 2967c478bd9Sstevel@tonic-gate rrip_name(sig_args_t *sig_args_p) 2977c478bd9Sstevel@tonic-gate { 2987c478bd9Sstevel@tonic-gate uchar_t *nm_ptr = sig_args_p->SUF_ptr; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate if ((sig_args_p->name_p == (uchar_t *)NULL) || 3017c478bd9Sstevel@tonic-gate (sig_args_p->name_len_p == (int *)NULL)) 3027c478bd9Sstevel@tonic-gate goto end; 3037c478bd9Sstevel@tonic-gate /* 3047c478bd9Sstevel@tonic-gate * If we have a "." or ".." directory, we should not look for 3057c478bd9Sstevel@tonic-gate * an alternate name 3067c478bd9Sstevel@tonic-gate */ 3077c478bd9Sstevel@tonic-gate if (HDE_NAME_LEN(sig_args_p->dirp) == 1) { 3087c478bd9Sstevel@tonic-gate if (*((char *)HDE_name(sig_args_p->dirp)) == '\0') { 3097c478bd9Sstevel@tonic-gate (void) strcpy((char *)sig_args_p->name_p, "."); 3107c478bd9Sstevel@tonic-gate *sig_args_p->name_len_p = 1; 3117c478bd9Sstevel@tonic-gate goto end; 3127c478bd9Sstevel@tonic-gate } else if (*((char *)HDE_name(sig_args_p->dirp)) == '\1') { 3137c478bd9Sstevel@tonic-gate (void) strcpy((char *)sig_args_p->name_p, ".."); 3147c478bd9Sstevel@tonic-gate *sig_args_p->name_len_p = 2; 3157c478bd9Sstevel@tonic-gate goto end; 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate name_parse((int)RRIP_NAME_FLAGS(nm_ptr), RRIP_name(nm_ptr), 3207c478bd9Sstevel@tonic-gate (size_t)RRIP_NAME_LEN(nm_ptr), sig_args_p->name_p, 3217c478bd9Sstevel@tonic-gate sig_args_p->name_len_p, &(sig_args_p->name_flags), 3227c478bd9Sstevel@tonic-gate MAXNAMELEN); 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate end: 3257c478bd9Sstevel@tonic-gate return (nm_ptr + SUF_LEN(nm_ptr)); 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate /* 3307c478bd9Sstevel@tonic-gate * rrip_sym_link() 3317c478bd9Sstevel@tonic-gate * 3327c478bd9Sstevel@tonic-gate * sig_handler() for RRIP signature RRIP_SL 3337c478bd9Sstevel@tonic-gate * 3347c478bd9Sstevel@tonic-gate * creates a symlink buffer to simulate sym_links. 3357c478bd9Sstevel@tonic-gate */ 3367c478bd9Sstevel@tonic-gate uchar_t * 3377c478bd9Sstevel@tonic-gate rrip_sym_link(sig_args_t *sig_args_p) 3387c478bd9Sstevel@tonic-gate { 3397c478bd9Sstevel@tonic-gate uchar_t *sl_ptr = sig_args_p->SUF_ptr; 3407c478bd9Sstevel@tonic-gate uchar_t *comp_ptr; 3417c478bd9Sstevel@tonic-gate char *tmp_sym_link; 3427c478bd9Sstevel@tonic-gate struct hs_direntry *hdp = sig_args_p->hdp; 3437c478bd9Sstevel@tonic-gate int sym_link_len; 3447c478bd9Sstevel@tonic-gate char *sym_link; 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate if (hdp->type != VLNK) 3477c478bd9Sstevel@tonic-gate goto end; 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate /* 3507c478bd9Sstevel@tonic-gate * If the sym link has already been created, don't recreate it 3517c478bd9Sstevel@tonic-gate */ 3527c478bd9Sstevel@tonic-gate if (IS_NAME_BIT_SET(sig_args_p->name_flags, RRIP_SYM_LINK_COMPLETE)) 3537c478bd9Sstevel@tonic-gate goto end; 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate sym_link = kmem_alloc(MAXPATHLEN + 1, KM_SLEEP); 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate /* 3587c478bd9Sstevel@tonic-gate * If there is an original string put it into sym_link[], otherwise 3597c478bd9Sstevel@tonic-gate * initialize sym_link[] to the empty string. 3607c478bd9Sstevel@tonic-gate */ 3617c478bd9Sstevel@tonic-gate if (hdp->sym_link != (char *)NULL) { 3627c478bd9Sstevel@tonic-gate sym_link_len = (int)strlen(strcpy(sym_link, hdp->sym_link)); 3637c478bd9Sstevel@tonic-gate } else { 3647c478bd9Sstevel@tonic-gate sym_link[0] = '\0'; 3657c478bd9Sstevel@tonic-gate sym_link_len = 0; 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate /* for all components */ 3697c478bd9Sstevel@tonic-gate for (comp_ptr = RRIP_sl_comp(sl_ptr); 3707c478bd9Sstevel@tonic-gate comp_ptr < (sl_ptr + SUF_LEN(sl_ptr)); 3717c478bd9Sstevel@tonic-gate comp_ptr += RRIP_COMP_LEN(comp_ptr)) { 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate name_parse((int)RRIP_COMP_FLAGS(comp_ptr), 3747c478bd9Sstevel@tonic-gate RRIP_comp(comp_ptr), 3757c478bd9Sstevel@tonic-gate (size_t)RRIP_COMP_NAME_LEN(comp_ptr), (uchar_t *)sym_link, 3767c478bd9Sstevel@tonic-gate &sym_link_len, &(sig_args_p->name_flags), 3777c478bd9Sstevel@tonic-gate MAXPATHLEN); 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate /* 380*2daa2183Sbatschul * If the component is continued don't put a '/' in 381*2daa2183Sbatschul * the pathname, but do NULL terminate it. 3827c478bd9Sstevel@tonic-gate */ 3837c478bd9Sstevel@tonic-gate if (IS_NAME_BIT_SET(RRIP_COMP_FLAGS(comp_ptr), 384*2daa2183Sbatschul RRIP_NAME_CONTINUE)) { 3857c478bd9Sstevel@tonic-gate sym_link[sym_link_len] = '\0'; 3867c478bd9Sstevel@tonic-gate } else { 3877c478bd9Sstevel@tonic-gate sym_link[sym_link_len] = '/'; 3887c478bd9Sstevel@tonic-gate sym_link[sym_link_len + 1] = '\0'; 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate /* add 1 to sym_link_len for '/' */ 3917c478bd9Sstevel@tonic-gate sym_link_len++; 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate /* 397*2daa2183Sbatschul * If we reached the end of the symbolic link, take out the 398*2daa2183Sbatschul * last slash, but don't change ROOT "/" to an empty string. 3997c478bd9Sstevel@tonic-gate */ 400*2daa2183Sbatschul if (!IS_NAME_BIT_SET(RRIP_SL_FLAGS(sl_ptr), RRIP_NAME_CONTINUE) && 401*2daa2183Sbatschul sym_link_len > 1 && sym_link[sym_link_len - 1] == '/') 4027c478bd9Sstevel@tonic-gate sym_link[--sym_link_len] = '\0'; 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate /* 4057c478bd9Sstevel@tonic-gate * if no memory has been allocated, get some, otherwise, append 4067c478bd9Sstevel@tonic-gate * to the current allocation 4077c478bd9Sstevel@tonic-gate */ 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate tmp_sym_link = kmem_alloc(SYM_LINK_LEN(sym_link), KM_SLEEP); 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate (void) strcpy(tmp_sym_link, sym_link); 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate if (hdp->sym_link != (char *)NULL) 4147c478bd9Sstevel@tonic-gate kmem_free(hdp->sym_link, (size_t)(hdp->ext_size + 1)); 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate hdp->sym_link = (char *)&tmp_sym_link[0]; 4177c478bd9Sstevel@tonic-gate /* the size of a symlink is its length */ 4187c478bd9Sstevel@tonic-gate hdp->ext_size = (uint_t)strlen(tmp_sym_link); 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate if (!IS_NAME_BIT_SET(RRIP_SL_FLAGS(sl_ptr), RRIP_NAME_CONTINUE)) { 4217c478bd9Sstevel@tonic-gate /* reached the end of the symbolic link */ 4227c478bd9Sstevel@tonic-gate SET_NAME_BIT(sig_args_p->name_flags, RRIP_SYM_LINK_COMPLETE); 4237c478bd9Sstevel@tonic-gate } 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate kmem_free(sym_link, MAXPATHLEN + 1); 4267c478bd9Sstevel@tonic-gate end: 4277c478bd9Sstevel@tonic-gate return (sl_ptr + SUF_LEN(sl_ptr)); 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate /* 4317c478bd9Sstevel@tonic-gate * rrip_namecopy() 4327c478bd9Sstevel@tonic-gate * 4337c478bd9Sstevel@tonic-gate * This function will copy the rrip name to the "to" buffer, if it 4347c478bd9Sstevel@tonic-gate * exists. 4357c478bd9Sstevel@tonic-gate * 4367c478bd9Sstevel@tonic-gate * XXX - We should speed this up by implementing the search in 4377c478bd9Sstevel@tonic-gate * parse_sua(). It works right now, so I don't want to mess with it. 4387c478bd9Sstevel@tonic-gate */ 4397c478bd9Sstevel@tonic-gate int 4407c478bd9Sstevel@tonic-gate rrip_namecopy( 4417c478bd9Sstevel@tonic-gate char *from, /* name to copy */ 4427c478bd9Sstevel@tonic-gate char *to, /* string to copy "from" to */ 4437c478bd9Sstevel@tonic-gate char *tmp_name, /* temp storage for original name */ 4447c478bd9Sstevel@tonic-gate uchar_t *dirp, /* directory entry pointer */ 445d10b6702Sfrankho uint_t last_offset, /* last index into current dir block */ 4467c478bd9Sstevel@tonic-gate struct hsfs *fsp, /* filesystem pointer */ 4477c478bd9Sstevel@tonic-gate struct hs_direntry *hdp) /* directory entry pointer to put */ 4487c478bd9Sstevel@tonic-gate /* all that good info in */ 4497c478bd9Sstevel@tonic-gate { 4507c478bd9Sstevel@tonic-gate int size = 0; 4517c478bd9Sstevel@tonic-gate int change_flag = 0; 4527c478bd9Sstevel@tonic-gate int ret_val; 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate if ((to == (char *)NULL) || 4557c478bd9Sstevel@tonic-gate (from == (char *)NULL) || 4567c478bd9Sstevel@tonic-gate (dirp == (uchar_t *)NULL)) { 4577c478bd9Sstevel@tonic-gate return (0); 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate /* special handling for '.' and '..' */ 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate if (HDE_NAME_LEN(dirp) == 1) { 4637c478bd9Sstevel@tonic-gate if (*((char *)HDE_name(dirp)) == '\0') { 4647c478bd9Sstevel@tonic-gate (void) strcpy(to, "."); 4657c478bd9Sstevel@tonic-gate return (1); 4667c478bd9Sstevel@tonic-gate } else if (*((char *)HDE_name(dirp)) == '\1') { 4677c478bd9Sstevel@tonic-gate (void) strcpy(to, ".."); 4687c478bd9Sstevel@tonic-gate return (2); 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate 473d10b6702Sfrankho ret_val = parse_sua((uchar_t *)to, &size, &change_flag, 474d10b6702Sfrankho dirp, last_offset, 4757c478bd9Sstevel@tonic-gate hdp, fsp, (uchar_t *)NULL, NULL); 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate if (IS_NAME_BIT_SET(change_flag, RRIP_NAME_CHANGE) && !ret_val) 4787c478bd9Sstevel@tonic-gate return (size); 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate /* 4817c478bd9Sstevel@tonic-gate * Well, the name was not found 4827c478bd9Sstevel@tonic-gate * 4837c478bd9Sstevel@tonic-gate * make rripname an upper case "nm" (to), so that 4847c478bd9Sstevel@tonic-gate * we can compare it the current HDE_DIR_NAME() 4857c478bd9Sstevel@tonic-gate * without nuking the original "nm", for future case 4867c478bd9Sstevel@tonic-gate * sensitive name comparing 4877c478bd9Sstevel@tonic-gate */ 4887c478bd9Sstevel@tonic-gate (void) strcpy(tmp_name, from); /* keep original */ 4897c478bd9Sstevel@tonic-gate size = hs_uppercase_copy(tmp_name, from, (int)strlen(from)); 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate return (-1); 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate /* 4977c478bd9Sstevel@tonic-gate * rrip_reloc_dir() 4987c478bd9Sstevel@tonic-gate * 4997c478bd9Sstevel@tonic-gate * This function is fairly bogus. All it does is cause a failure of 5007c478bd9Sstevel@tonic-gate * the hs_parsedir, so that no vnode will be made for it and 5017c478bd9Sstevel@tonic-gate * essentially, the directory will no longer be seen. This is part 5027c478bd9Sstevel@tonic-gate * of the directory hierarchy mess, where the relocated directory will 5037c478bd9Sstevel@tonic-gate * be hidden as far as ISO 9660 is concerned. When we hit the child 5047c478bd9Sstevel@tonic-gate * link "CL" SUF, then we will read the new directory. 5057c478bd9Sstevel@tonic-gate */ 5067c478bd9Sstevel@tonic-gate uchar_t * 5077c478bd9Sstevel@tonic-gate rrip_reloc_dir(sig_args_t *sig_args_p) 5087c478bd9Sstevel@tonic-gate { 5097c478bd9Sstevel@tonic-gate uchar_t *re_ptr = sig_args_p->SUF_ptr; 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate sig_args_p->flags = RELOC_DIR; 5127c478bd9Sstevel@tonic-gate 5137c478bd9Sstevel@tonic-gate return (re_ptr + SUF_LEN(re_ptr)); 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate /* 5197c478bd9Sstevel@tonic-gate * rrip_child_link() 5207c478bd9Sstevel@tonic-gate * 5217c478bd9Sstevel@tonic-gate * This is the child link part of the directory hierarchy stuff and 5227c478bd9Sstevel@tonic-gate * this does not really do much anyway. All it does is read the 5237c478bd9Sstevel@tonic-gate * directory entry that the child link SUF contains. All should be 5247c478bd9Sstevel@tonic-gate * fine then. 5257c478bd9Sstevel@tonic-gate */ 5267c478bd9Sstevel@tonic-gate uchar_t * 5277c478bd9Sstevel@tonic-gate rrip_child_link(sig_args_t *sig_args_p) 5287c478bd9Sstevel@tonic-gate { 5297c478bd9Sstevel@tonic-gate uchar_t *cl_ptr = sig_args_p->SUF_ptr; 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate sig_args_p->hdp->ext_lbn = RRIP_CHILD_LBN(cl_ptr); 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate hs_filldirent(sig_args_p->fsp->hsfs_rootvp, sig_args_p->hdp); 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate sig_args_p->flags = 0; 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate return (cl_ptr + SUF_LEN(cl_ptr)); 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate /* 5427c478bd9Sstevel@tonic-gate * rrip_parent_link() 5437c478bd9Sstevel@tonic-gate * 5447c478bd9Sstevel@tonic-gate * This is the parent link part of the directory hierarchy stuff and 5457c478bd9Sstevel@tonic-gate * this does not really do much anyway. All it does is read the 5467c478bd9Sstevel@tonic-gate * directory entry that the parent link SUF contains. All should be 5477c478bd9Sstevel@tonic-gate * fine then. 5487c478bd9Sstevel@tonic-gate */ 5497c478bd9Sstevel@tonic-gate uchar_t * 5507c478bd9Sstevel@tonic-gate rrip_parent_link(sig_args_t *sig_args_p) 5517c478bd9Sstevel@tonic-gate { 5527c478bd9Sstevel@tonic-gate uchar_t *pl_ptr = sig_args_p->SUF_ptr; 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate sig_args_p->hdp->ext_lbn = RRIP_PARENT_LBN(pl_ptr); 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate hs_filldirent(sig_args_p->fsp->hsfs_rootvp, sig_args_p->hdp); 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate sig_args_p->flags = 0; 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate return (pl_ptr + SUF_LEN(pl_ptr)); 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate /* 5657c478bd9Sstevel@tonic-gate * rrip_rock_ridge() 5667c478bd9Sstevel@tonic-gate * 5677c478bd9Sstevel@tonic-gate * This function is supposed to aid in speed of the filesystem. 5687c478bd9Sstevel@tonic-gate * 5697c478bd9Sstevel@tonic-gate * XXX - It is only here as a place holder so far. 5707c478bd9Sstevel@tonic-gate */ 5717c478bd9Sstevel@tonic-gate uchar_t * 5727c478bd9Sstevel@tonic-gate rrip_rock_ridge(sig_args_t *sig_args_p) 5737c478bd9Sstevel@tonic-gate { 5747c478bd9Sstevel@tonic-gate uchar_t *rr_ptr = sig_args_p->SUF_ptr; 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate return (rr_ptr + SUF_LEN(rr_ptr)); 5777c478bd9Sstevel@tonic-gate } 578