1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * ISO 9660 System Use Sharing Protocol extension filesystem specifications 24 * Copyright (c) 1991,2000,2001 by Sun Microsystems, Inc. 25 * All rights reserved. 26 */ 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <sys/types.h> 31 #include <sys/t_lock.h> 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/sysmacros.h> 35 #include <sys/kmem.h> 36 #include <sys/signal.h> 37 #include <sys/user.h> 38 #include <sys/proc.h> 39 #include <sys/disp.h> 40 #include <sys/buf.h> 41 #include <sys/pathname.h> 42 #include <sys/vfs.h> 43 #include <sys/vnode.h> 44 #include <sys/file.h> 45 #include <sys/uio.h> 46 #include <sys/conf.h> 47 48 #include <vm/page.h> 49 50 #include <sys/fs/hsfs_spec.h> 51 #include <sys/fs/hsfs_isospec.h> 52 #include <sys/fs/hsfs_node.h> 53 #include <sys/fs/hsfs_impl.h> 54 #include <sys/fs/hsfs_susp.h> 55 #include <sys/fs/hsfs_rrip.h> 56 57 #include <sys/statvfs.h> 58 #include <sys/mount.h> 59 #include <sys/swap.h> 60 #include <sys/errno.h> 61 #include <sys/debug.h> 62 #include "fs/fs_subr.h" 63 #include <sys/cmn_err.h> 64 65 66 67 /* 68 * Common Signatures for all SUSP 69 */ 70 ext_signature_t susp_signature_table[ ] = { 71 SUSP_SP, share_protocol, /* must be first in table */ 72 SUSP_CE, share_continue, /* must be second in table */ 73 SUSP_PD, share_padding, 74 SUSP_ER, share_ext_ref, 75 SUSP_ST, share_stop, 76 (char *)NULL, NULL 77 }; 78 79 /* 80 * These are global pointers referring to the above table, so the 81 * positions must not change as marked on the right above. 82 */ 83 ext_signature_t *susp_sp = &susp_signature_table[0]; 84 ext_signature_t *susp_ce = &susp_signature_table[1]; 85 86 87 /* 88 * ext name version implemented signature table 89 * 90 * the SUSP must be the first entry in the table. 91 * the RRIP must be the second entry in the table. We need to be able 92 * to check the RRIP bit being set, so we must know it's position. 93 * RRIP_BIT is set to 2 in rrip.h 94 */ 95 extension_name_t extension_name_table[] = { 96 "SUSP_1991A", SUSP_VERSION, susp_signature_table, /* #1 */ 97 RRIP_ER_EXT_ID, RRIP_EXT_VERSION, rrip_signature_table, 98 (char *)NULL, 0, (ext_signature_t *)NULL 99 }; 100 101 extension_name_t *susp_ext_name = extension_name_table; 102 103 /* 104 * share_protocol() 105 * 106 * sig_handler() for SUSP signature "SP" 107 * 108 * This function looks for the "SP" signature field, which means that 109 * the SUSP is supported on the current CD-ROM. It looks for the word 110 * 0xBEEF in the signature. If that exists, the SUSP is implemented. 111 * The function will then set the implemented bit in the "SUSP" entry 112 * of the extention_name_table[]. If the bytes don't match, then we 113 * return a big fat NULL and treat this as an ISO 9660 CD-ROM. 114 */ 115 uchar_t * 116 share_protocol(sig_args_t *sig_args_p) 117 { 118 uchar_t *sp_ptr = sig_args_p->SUF_ptr; 119 120 /* Let's check the check bytes */ 121 if (!CHECK_BYTES_OK(sp_ptr)) 122 return ((uchar_t *)NULL); 123 124 /* 125 * Ah, we have the go ahead, so let's set the implemented bit 126 * of the SUSP in the extension_name_table[] 127 */ 128 129 if (SUSP_VERSION < SUF_VER(sp_ptr)) { 130 cmn_err(CE_NOTE, 131 "System Use Sharing Protocol ver. %d:not supported\n", 132 (int)SUF_VER(sp_ptr)); 133 return ((uchar_t *)NULL); 134 } 135 136 SET_SUSP_BIT(sig_args_p->fsp); 137 138 sig_args_p->fsp->hsfs_sua_off = SP_SUA_OFFSET(sp_ptr); 139 140 return (sp_ptr + SUF_LEN(sp_ptr)); 141 } 142 143 /* 144 * share_ext_ref() 145 * 146 * sig_handler() for SUSP signature "ER" 147 * 148 * This function looks for the "ER" signature field, which lists an 149 * extension that is implemented on the current CD-ROM. The function 150 * will then search through the extention_name_table[], looking for the 151 * extension reference in this SUF. 152 * 153 * If the correct extension reference is found, and the version number 154 * in the "ER" SUF is less than or equal to the version specified in 155 * the extension_name_table, the implemented bit will be set to 1. 156 * 157 * If the version number in the "ER" field is greater than that in the 158 * extension_name_table or no reference can be matched, the reference 159 * will be skipped the function will return the next field. 160 */ 161 uchar_t * 162 share_ext_ref(sig_args_t *sig_args_p) 163 { 164 uchar_t *er_ptr = sig_args_p->SUF_ptr; 165 extension_name_t *extnp; 166 int index; 167 168 /* 169 * Find appropriate extension and signature table 170 */ 171 for (extnp = extension_name_table, index = 0; 172 extnp->extension_name != (char *)NULL; 173 extnp++, index++) { 174 if (strncmp(extnp->extension_name, 175 (char *)ER_ext_id(er_ptr), 176 ER_ID_LEN(er_ptr)) == 0) { 177 SET_IMPL_BIT(sig_args_p->fsp, index); 178 } 179 } 180 181 return (er_ptr + SUF_LEN(er_ptr)); 182 } 183 184 /* 185 * share_continue() 186 * 187 * sig_handler() for SUSP signature "CE" 188 * 189 * This function looks for the "CE" signature field. This means that 190 * the SUA is continued in another block on the CD-ROM. Because it is 191 * not a requirement that this "CE" field come at the end of the SUA, 192 * this function will only set up a structure containing the 193 * information needed to read the next SUA, somewhere on the disk. 194 * 195 * The end of the SUA is signaled by 2 NULL bytes, where the next 196 * signature would have been. 197 * 198 * This one will be tough to implement. 199 */ 200 uchar_t * 201 share_continue(sig_args_t *sig_args_p) 202 { 203 uchar_t *ce_ptr = sig_args_p->SUF_ptr; 204 205 sig_args_p->cont_info_p->cont_lbn = CE_BLK_LOC(ce_ptr); 206 sig_args_p->cont_info_p->cont_offset = CE_OFFSET(ce_ptr); 207 sig_args_p->cont_info_p->cont_len = CE_CONT_LEN(ce_ptr); 208 209 return (ce_ptr + SUF_LEN(ce_ptr)); 210 } 211 212 213 /* 214 * share_padding() 215 * 216 * sig_handler() for SUSP signature "PD" 217 * 218 * All this function is needed for is bypassing a certain number of 219 * bytes. So, we just advance past this field and we're set. 220 */ 221 uchar_t * 222 share_padding(sig_args_t *sig_args_p) 223 { 224 uchar_t *pd_ptr = sig_args_p->SUF_ptr; 225 226 return (pd_ptr + SUF_LEN(pd_ptr)); 227 } 228 229 230 231 /* 232 * share_stop() 233 * 234 * sig_handler() for SUSP signature "ST" 235 * 236 * All this is used for is signaling the end of an SUA. 237 * It fills the flag variable with the 238 */ 239 uchar_t * 240 share_stop(sig_args_t *sig_args_p) 241 { 242 uchar_t *st_ptr = sig_args_p->SUF_ptr; 243 244 sig_args_p->flags = END_OF_SUA; /* stop parsing the SUA NOW!!!! */ 245 246 return (st_ptr + SUF_LEN(st_ptr)); 247 } 248