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