1df8bae1dSRodney W. Grimes /*- 2df8bae1dSRodney W. Grimes * Copyright (c) 1993, 1994 3df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved. 4df8bae1dSRodney W. Grimes * 5df8bae1dSRodney W. Grimes * This code is derived from software contributed to Berkeley 6df8bae1dSRodney W. Grimes * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension 7df8bae1dSRodney W. Grimes * Support code is derived from software contributed to Berkeley 8df8bae1dSRodney W. Grimes * by Atsushi Murai (amurai@spec.co.jp). 9df8bae1dSRodney W. Grimes * 10df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 11df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions 12df8bae1dSRodney W. Grimes * are met: 13df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 14df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 15df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 16df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 17df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution. 18df8bae1dSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 19df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 20df8bae1dSRodney W. Grimes * without specific prior written permission. 21df8bae1dSRodney W. Grimes * 22df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32df8bae1dSRodney W. Grimes * SUCH DAMAGE. 33df8bae1dSRodney W. Grimes * 34996c772fSJohn Dyson * @(#)cd9660_rrip.c 8.6 (Berkeley) 12/5/94 35df8bae1dSRodney W. Grimes */ 36df8bae1dSRodney W. Grimes 378c9bbf48SDavid E. O'Brien #include <sys/cdefs.h> 388c9bbf48SDavid E. O'Brien __FBSDID("$FreeBSD$"); 398c9bbf48SDavid E. O'Brien 40df8bae1dSRodney W. Grimes #include <sys/param.h> 411dbaf90cSBruce Evans #include <sys/systm.h> 429626b608SPoul-Henning Kamp #include <sys/bio.h> 43df8bae1dSRodney W. Grimes #include <sys/buf.h> 4476ca6f88SJamie Gritton #include <sys/jail.h> 45df8bae1dSRodney W. Grimes #include <sys/vnode.h> 46df8bae1dSRodney W. Grimes #include <sys/mount.h> 47df8bae1dSRodney W. Grimes #include <sys/kernel.h> 48df8bae1dSRodney W. Grimes 49a8d36d0dSCraig Rodrigues #include <fs/cd9660/iso.h> 50a8d36d0dSCraig Rodrigues #include <fs/cd9660/cd9660_node.h> 51a8d36d0dSCraig Rodrigues #include <fs/cd9660/cd9660_rrip.h> 52a8d36d0dSCraig Rodrigues #include <fs/cd9660/iso_rrip.h> 53df8bae1dSRodney W. Grimes 5489c9a483SAlfred Perlstein typedef int rrt_func_t(void *, ISO_RRIP_ANALYZE *ana); 5510dd32cdSBruce Evans 5610dd32cdSBruce Evans typedef struct { 5710dd32cdSBruce Evans char type[2]; 5810dd32cdSBruce Evans rrt_func_t *func; 5989c9a483SAlfred Perlstein void (*func2)(struct iso_directory_record *isodir, ISO_RRIP_ANALYZE *ana); 6010dd32cdSBruce Evans int result; 6110dd32cdSBruce Evans } RRIP_TABLE; 6210dd32cdSBruce Evans 6389c9a483SAlfred Perlstein static int cd9660_rrip_altname(ISO_RRIP_ALTNAME *p, ISO_RRIP_ANALYZE *ana); 6489c9a483SAlfred Perlstein static int cd9660_rrip_attr(ISO_RRIP_ATTR *p, ISO_RRIP_ANALYZE *ana); 6589c9a483SAlfred Perlstein static int cd9660_rrip_cont(ISO_RRIP_CONT *p, ISO_RRIP_ANALYZE *ana); 6689c9a483SAlfred Perlstein static void cd9660_rrip_defattr(struct iso_directory_record *isodir, 6789c9a483SAlfred Perlstein ISO_RRIP_ANALYZE *ana); 6889c9a483SAlfred Perlstein static void cd9660_rrip_defname(struct iso_directory_record *isodir, 6989c9a483SAlfred Perlstein ISO_RRIP_ANALYZE *ana); 7089c9a483SAlfred Perlstein static void cd9660_rrip_deftstamp(struct iso_directory_record *isodir, 7189c9a483SAlfred Perlstein ISO_RRIP_ANALYZE *ana); 7289c9a483SAlfred Perlstein static int cd9660_rrip_device(ISO_RRIP_DEVICE *p, ISO_RRIP_ANALYZE *ana); 7389c9a483SAlfred Perlstein static int cd9660_rrip_extref(ISO_RRIP_EXTREF *p, ISO_RRIP_ANALYZE *ana); 7489c9a483SAlfred Perlstein static int cd9660_rrip_idflag(ISO_RRIP_IDFLAG *p, ISO_RRIP_ANALYZE *ana); 7589c9a483SAlfred Perlstein static int cd9660_rrip_loop(struct iso_directory_record *isodir, 7669c59d87SBruce Evans ISO_RRIP_ANALYZE *ana, RRIP_TABLE *table); 7789c9a483SAlfred Perlstein static int cd9660_rrip_pclink(ISO_RRIP_CLINK *p, ISO_RRIP_ANALYZE *ana); 7889c9a483SAlfred Perlstein static int cd9660_rrip_reldir(ISO_RRIP_RELDIR *p, ISO_RRIP_ANALYZE *ana); 7989c9a483SAlfred Perlstein static int cd9660_rrip_slink(ISO_RRIP_SLINK *p, ISO_RRIP_ANALYZE *ana); 8089c9a483SAlfred Perlstein static int cd9660_rrip_stop(ISO_SUSP_HEADER *p, ISO_RRIP_ANALYZE *ana); 8189c9a483SAlfred Perlstein static int cd9660_rrip_tstamp(ISO_RRIP_TSTAMP *p, ISO_RRIP_ANALYZE *ana); 8210dd32cdSBruce Evans 83df8bae1dSRodney W. Grimes /* 84df8bae1dSRodney W. Grimes * POSIX file attribute 85df8bae1dSRodney W. Grimes */ 86df8bae1dSRodney W. Grimes static int 87df8bae1dSRodney W. Grimes cd9660_rrip_attr(p,ana) 88df8bae1dSRodney W. Grimes ISO_RRIP_ATTR *p; 89df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 90df8bae1dSRodney W. Grimes { 91996c772fSJohn Dyson ana->inop->inode.iso_mode = isonum_733(p->mode); 92996c772fSJohn Dyson ana->inop->inode.iso_uid = isonum_733(p->uid); 93996c772fSJohn Dyson ana->inop->inode.iso_gid = isonum_733(p->gid); 94996c772fSJohn Dyson ana->inop->inode.iso_links = isonum_733(p->links); 95df8bae1dSRodney W. Grimes ana->fields &= ~ISO_SUSP_ATTR; 96df8bae1dSRodney W. Grimes return ISO_SUSP_ATTR; 97df8bae1dSRodney W. Grimes } 98df8bae1dSRodney W. Grimes 99df8bae1dSRodney W. Grimes static void 100df8bae1dSRodney W. Grimes cd9660_rrip_defattr(isodir,ana) 101df8bae1dSRodney W. Grimes struct iso_directory_record *isodir; 102df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 103df8bae1dSRodney W. Grimes { 104df8bae1dSRodney W. Grimes /* But this is a required field! */ 105df8bae1dSRodney W. Grimes printf("RRIP without PX field?\n"); 106988fa8efSJoerg Wunsch cd9660_defattr(isodir,ana->inop,NULL,ISO_FTYPE_RRIP); 107df8bae1dSRodney W. Grimes } 108df8bae1dSRodney W. Grimes 109df8bae1dSRodney W. Grimes /* 110df8bae1dSRodney W. Grimes * Symbolic Links 111df8bae1dSRodney W. Grimes */ 112df8bae1dSRodney W. Grimes static int 113df8bae1dSRodney W. Grimes cd9660_rrip_slink(p,ana) 114df8bae1dSRodney W. Grimes ISO_RRIP_SLINK *p; 115df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 116df8bae1dSRodney W. Grimes { 117bffd1b7aSPoul-Henning Kamp ISO_RRIP_SLINK_COMPONENT *pcomp; 118bffd1b7aSPoul-Henning Kamp ISO_RRIP_SLINK_COMPONENT *pcompe; 119df8bae1dSRodney W. Grimes int len, wlen, cont; 120df8bae1dSRodney W. Grimes char *outbuf, *inbuf; 12176ca6f88SJamie Gritton char hostbuf[MAXHOSTNAMELEN]; 122df8bae1dSRodney W. Grimes 123df8bae1dSRodney W. Grimes pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component; 124df8bae1dSRodney W. Grimes pcompe = (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length)); 125df8bae1dSRodney W. Grimes len = *ana->outlen; 126df8bae1dSRodney W. Grimes outbuf = ana->outbuf; 127df8bae1dSRodney W. Grimes cont = ana->cont; 128df8bae1dSRodney W. Grimes 129df8bae1dSRodney W. Grimes /* 130df8bae1dSRodney W. Grimes * Gathering a Symbolic name from each component with path 131df8bae1dSRodney W. Grimes */ 132df8bae1dSRodney W. Grimes for (; 133df8bae1dSRodney W. Grimes pcomp < pcompe; 134df8bae1dSRodney W. Grimes pcomp = (ISO_RRIP_SLINK_COMPONENT *)((char *)pcomp + ISO_RRIP_SLSIZ 135df8bae1dSRodney W. Grimes + isonum_711(pcomp->clen))) { 136df8bae1dSRodney W. Grimes 137df8bae1dSRodney W. Grimes if (!cont) { 138df8bae1dSRodney W. Grimes if (len < ana->maxlen) { 139df8bae1dSRodney W. Grimes len++; 140df8bae1dSRodney W. Grimes *outbuf++ = '/'; 141df8bae1dSRodney W. Grimes } 142df8bae1dSRodney W. Grimes } 143df8bae1dSRodney W. Grimes cont = 0; 144df8bae1dSRodney W. Grimes 145df8bae1dSRodney W. Grimes inbuf = ".."; 146df8bae1dSRodney W. Grimes wlen = 0; 147df8bae1dSRodney W. Grimes 148df8bae1dSRodney W. Grimes switch (*pcomp->cflag) { 149df8bae1dSRodney W. Grimes 150df8bae1dSRodney W. Grimes case ISO_SUSP_CFLAG_CURRENT: 151df8bae1dSRodney W. Grimes /* Inserting Current */ 152df8bae1dSRodney W. Grimes wlen = 1; 153df8bae1dSRodney W. Grimes break; 154df8bae1dSRodney W. Grimes 155df8bae1dSRodney W. Grimes case ISO_SUSP_CFLAG_PARENT: 156df8bae1dSRodney W. Grimes /* Inserting Parent */ 157df8bae1dSRodney W. Grimes wlen = 2; 158df8bae1dSRodney W. Grimes break; 159df8bae1dSRodney W. Grimes 160df8bae1dSRodney W. Grimes case ISO_SUSP_CFLAG_ROOT: 161df8bae1dSRodney W. Grimes /* Inserting slash for ROOT */ 162f7d5a532SJoerg Wunsch /* Double slash, nothing really to do here. */ 163df8bae1dSRodney W. Grimes break; 164df8bae1dSRodney W. Grimes 165df8bae1dSRodney W. Grimes case ISO_SUSP_CFLAG_VOLROOT: 166df8bae1dSRodney W. Grimes /* Inserting a mount point i.e. "/cdrom" */ 167df8bae1dSRodney W. Grimes /* same as above */ 168df8bae1dSRodney W. Grimes outbuf -= len; 169df8bae1dSRodney W. Grimes len = 0; 170df8bae1dSRodney W. Grimes inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname; 171df8bae1dSRodney W. Grimes wlen = strlen(inbuf); 172df8bae1dSRodney W. Grimes break; 173df8bae1dSRodney W. Grimes 174df8bae1dSRodney W. Grimes case ISO_SUSP_CFLAG_HOST: 175df8bae1dSRodney W. Grimes /* Inserting hostname i.e. "kurt.tools.de" */ 17676ca6f88SJamie Gritton getcredhostname(curthread->td_ucred, hostbuf, 17776ca6f88SJamie Gritton sizeof(hostbuf)); 17876ca6f88SJamie Gritton inbuf = hostbuf; 17976ca6f88SJamie Gritton wlen = strlen(inbuf); 180df8bae1dSRodney W. Grimes break; 181df8bae1dSRodney W. Grimes 182df8bae1dSRodney W. Grimes case ISO_SUSP_CFLAG_CONTINUE: 183df8bae1dSRodney W. Grimes cont = 1; 18493b0017fSPhilippe Charnier /* FALLTHROUGH */ 185df8bae1dSRodney W. Grimes case 0: 186df8bae1dSRodney W. Grimes /* Inserting component */ 187df8bae1dSRodney W. Grimes wlen = isonum_711(pcomp->clen); 188df8bae1dSRodney W. Grimes inbuf = pcomp->name; 189df8bae1dSRodney W. Grimes break; 190df8bae1dSRodney W. Grimes default: 191df8bae1dSRodney W. Grimes printf("RRIP with incorrect flags?"); 192df8bae1dSRodney W. Grimes wlen = ana->maxlen + 1; 193df8bae1dSRodney W. Grimes break; 194df8bae1dSRodney W. Grimes } 195df8bae1dSRodney W. Grimes 196df8bae1dSRodney W. Grimes if (len + wlen > ana->maxlen) { 197df8bae1dSRodney W. Grimes /* indicate error to caller */ 198df8bae1dSRodney W. Grimes ana->cont = 1; 199df8bae1dSRodney W. Grimes ana->fields = 0; 200df8bae1dSRodney W. Grimes ana->outbuf -= *ana->outlen; 201df8bae1dSRodney W. Grimes *ana->outlen = 0; 202df8bae1dSRodney W. Grimes return 0; 203df8bae1dSRodney W. Grimes } 204df8bae1dSRodney W. Grimes 205df8bae1dSRodney W. Grimes bcopy(inbuf,outbuf,wlen); 206df8bae1dSRodney W. Grimes outbuf += wlen; 207df8bae1dSRodney W. Grimes len += wlen; 208df8bae1dSRodney W. Grimes 209df8bae1dSRodney W. Grimes } 210df8bae1dSRodney W. Grimes ana->outbuf = outbuf; 211df8bae1dSRodney W. Grimes *ana->outlen = len; 212df8bae1dSRodney W. Grimes ana->cont = cont; 213df8bae1dSRodney W. Grimes 214df8bae1dSRodney W. Grimes if (!isonum_711(p->flags)) { 215df8bae1dSRodney W. Grimes ana->fields &= ~ISO_SUSP_SLINK; 216df8bae1dSRodney W. Grimes return ISO_SUSP_SLINK; 217df8bae1dSRodney W. Grimes } 218df8bae1dSRodney W. Grimes return 0; 219df8bae1dSRodney W. Grimes } 220df8bae1dSRodney W. Grimes 221df8bae1dSRodney W. Grimes /* 222df8bae1dSRodney W. Grimes * Alternate name 223df8bae1dSRodney W. Grimes */ 224df8bae1dSRodney W. Grimes static int 225df8bae1dSRodney W. Grimes cd9660_rrip_altname(p,ana) 226df8bae1dSRodney W. Grimes ISO_RRIP_ALTNAME *p; 227df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 228df8bae1dSRodney W. Grimes { 229df8bae1dSRodney W. Grimes char *inbuf; 230df8bae1dSRodney W. Grimes int wlen; 231df8bae1dSRodney W. Grimes int cont; 23276ca6f88SJamie Gritton char hostbuf[MAXHOSTNAMELEN]; 233df8bae1dSRodney W. Grimes 234df8bae1dSRodney W. Grimes inbuf = ".."; 235df8bae1dSRodney W. Grimes wlen = 0; 236df8bae1dSRodney W. Grimes cont = 0; 237df8bae1dSRodney W. Grimes 238df8bae1dSRodney W. Grimes switch (*p->flags) { 239df8bae1dSRodney W. Grimes case ISO_SUSP_CFLAG_CURRENT: 240df8bae1dSRodney W. Grimes /* Inserting Current */ 241df8bae1dSRodney W. Grimes wlen = 1; 242df8bae1dSRodney W. Grimes break; 243df8bae1dSRodney W. Grimes 244df8bae1dSRodney W. Grimes case ISO_SUSP_CFLAG_PARENT: 245df8bae1dSRodney W. Grimes /* Inserting Parent */ 246df8bae1dSRodney W. Grimes wlen = 2; 247df8bae1dSRodney W. Grimes break; 248df8bae1dSRodney W. Grimes 249df8bae1dSRodney W. Grimes case ISO_SUSP_CFLAG_HOST: 250df8bae1dSRodney W. Grimes /* Inserting hostname i.e. "kurt.tools.de" */ 25176ca6f88SJamie Gritton getcredhostname(curthread->td_ucred, hostbuf, sizeof(hostbuf)); 25276ca6f88SJamie Gritton inbuf = hostbuf; 25376ca6f88SJamie Gritton wlen = strlen(inbuf); 254df8bae1dSRodney W. Grimes break; 255df8bae1dSRodney W. Grimes 256df8bae1dSRodney W. Grimes case ISO_SUSP_CFLAG_CONTINUE: 257df8bae1dSRodney W. Grimes cont = 1; 25893b0017fSPhilippe Charnier /* FALLTHROUGH */ 259df8bae1dSRodney W. Grimes case 0: 260df8bae1dSRodney W. Grimes /* Inserting component */ 261df8bae1dSRodney W. Grimes wlen = isonum_711(p->h.length) - 5; 262df8bae1dSRodney W. Grimes inbuf = (char *)p + 5; 263df8bae1dSRodney W. Grimes break; 264df8bae1dSRodney W. Grimes 265df8bae1dSRodney W. Grimes default: 266df8bae1dSRodney W. Grimes printf("RRIP with incorrect NM flags?\n"); 267df8bae1dSRodney W. Grimes wlen = ana->maxlen + 1; 268df8bae1dSRodney W. Grimes break; 269df8bae1dSRodney W. Grimes } 270df8bae1dSRodney W. Grimes 271df8bae1dSRodney W. Grimes if ((*ana->outlen += wlen) > ana->maxlen) { 272df8bae1dSRodney W. Grimes /* treat as no name field */ 273df8bae1dSRodney W. Grimes ana->fields &= ~ISO_SUSP_ALTNAME; 274df8bae1dSRodney W. Grimes ana->outbuf -= *ana->outlen - wlen; 275df8bae1dSRodney W. Grimes *ana->outlen = 0; 276df8bae1dSRodney W. Grimes return 0; 277df8bae1dSRodney W. Grimes } 278df8bae1dSRodney W. Grimes 279df8bae1dSRodney W. Grimes bcopy(inbuf,ana->outbuf,wlen); 280df8bae1dSRodney W. Grimes ana->outbuf += wlen; 281df8bae1dSRodney W. Grimes 282df8bae1dSRodney W. Grimes if (!cont) { 283df8bae1dSRodney W. Grimes ana->fields &= ~ISO_SUSP_ALTNAME; 284df8bae1dSRodney W. Grimes return ISO_SUSP_ALTNAME; 285df8bae1dSRodney W. Grimes } 286df8bae1dSRodney W. Grimes return 0; 287df8bae1dSRodney W. Grimes } 288df8bae1dSRodney W. Grimes 289df8bae1dSRodney W. Grimes static void 290df8bae1dSRodney W. Grimes cd9660_rrip_defname(isodir,ana) 291df8bae1dSRodney W. Grimes struct iso_directory_record *isodir; 292df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 293df8bae1dSRodney W. Grimes { 294df8bae1dSRodney W. Grimes isofntrans(isodir->name,isonum_711(isodir->name_len), 295df8bae1dSRodney W. Grimes ana->outbuf,ana->outlen, 296c4f02a89SMax Khon 1,isonum_711(isodir->flags)&4, ana->imp->joliet_level, 297c4f02a89SMax Khon ana->imp->im_flags, ana->imp->im_d2l); 29844e568e2SDaniel C. Sobral switch (*ana->outbuf) { 29944e568e2SDaniel C. Sobral default: 300df8bae1dSRodney W. Grimes break; 301df8bae1dSRodney W. Grimes case 1: 302df8bae1dSRodney W. Grimes *ana->outlen = 2; 30344e568e2SDaniel C. Sobral /* FALLTHROUGH */ 30444e568e2SDaniel C. Sobral case 0: 30544e568e2SDaniel C. Sobral /* outlen is 1 already */ 30644e568e2SDaniel C. Sobral strcpy(ana->outbuf,".."); 307df8bae1dSRodney W. Grimes break; 308df8bae1dSRodney W. Grimes } 309df8bae1dSRodney W. Grimes } 310df8bae1dSRodney W. Grimes 311df8bae1dSRodney W. Grimes /* 312df8bae1dSRodney W. Grimes * Parent or Child Link 313df8bae1dSRodney W. Grimes */ 314df8bae1dSRodney W. Grimes static int 315df8bae1dSRodney W. Grimes cd9660_rrip_pclink(p,ana) 316df8bae1dSRodney W. Grimes ISO_RRIP_CLINK *p; 317df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 318df8bae1dSRodney W. Grimes { 319df8bae1dSRodney W. Grimes *ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift; 320df8bae1dSRodney W. Grimes ana->fields &= ~(ISO_SUSP_CLINK|ISO_SUSP_PLINK); 321df8bae1dSRodney W. Grimes return *p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK; 322df8bae1dSRodney W. Grimes } 323df8bae1dSRodney W. Grimes 324df8bae1dSRodney W. Grimes /* 325df8bae1dSRodney W. Grimes * Relocated directory 326df8bae1dSRodney W. Grimes */ 327df8bae1dSRodney W. Grimes static int 328df8bae1dSRodney W. Grimes cd9660_rrip_reldir(p,ana) 329df8bae1dSRodney W. Grimes ISO_RRIP_RELDIR *p; 330df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 331df8bae1dSRodney W. Grimes { 332df8bae1dSRodney W. Grimes /* special hack to make caller aware of RE field */ 333df8bae1dSRodney W. Grimes *ana->outlen = 0; 334df8bae1dSRodney W. Grimes ana->fields = 0; 335df8bae1dSRodney W. Grimes return ISO_SUSP_RELDIR|ISO_SUSP_ALTNAME|ISO_SUSP_CLINK|ISO_SUSP_PLINK; 336df8bae1dSRodney W. Grimes } 337df8bae1dSRodney W. Grimes 338df8bae1dSRodney W. Grimes static int 339df8bae1dSRodney W. Grimes cd9660_rrip_tstamp(p,ana) 340df8bae1dSRodney W. Grimes ISO_RRIP_TSTAMP *p; 341df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 342df8bae1dSRodney W. Grimes { 343996c772fSJohn Dyson u_char *ptime; 344df8bae1dSRodney W. Grimes 345df8bae1dSRodney W. Grimes ptime = p->time; 346df8bae1dSRodney W. Grimes 347df8bae1dSRodney W. Grimes /* Check a format of time stamp (7bytes/17bytes) */ 348df8bae1dSRodney W. Grimes if (!(*p->flags&ISO_SUSP_TSTAMP_FORM17)) { 349df8bae1dSRodney W. Grimes if (*p->flags&ISO_SUSP_TSTAMP_CREAT) 350df8bae1dSRodney W. Grimes ptime += 7; 351df8bae1dSRodney W. Grimes 352df8bae1dSRodney W. Grimes if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) { 353988fa8efSJoerg Wunsch cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_mtime, 354988fa8efSJoerg Wunsch ISO_FTYPE_RRIP); 355df8bae1dSRodney W. Grimes ptime += 7; 356df8bae1dSRodney W. Grimes } else 3571dbaf90cSBruce Evans bzero(&ana->inop->inode.iso_mtime,sizeof(struct timespec)); 358df8bae1dSRodney W. Grimes 359df8bae1dSRodney W. Grimes if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) { 360988fa8efSJoerg Wunsch cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_atime, 361988fa8efSJoerg Wunsch ISO_FTYPE_RRIP); 362df8bae1dSRodney W. Grimes ptime += 7; 363df8bae1dSRodney W. Grimes } else 364df8bae1dSRodney W. Grimes ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime; 365df8bae1dSRodney W. Grimes 366df8bae1dSRodney W. Grimes if (*p->flags&ISO_SUSP_TSTAMP_ATTR) 367988fa8efSJoerg Wunsch cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_ctime, 368988fa8efSJoerg Wunsch ISO_FTYPE_RRIP); 369df8bae1dSRodney W. Grimes else 370df8bae1dSRodney W. Grimes ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime; 371df8bae1dSRodney W. Grimes 372df8bae1dSRodney W. Grimes } else { 373df8bae1dSRodney W. Grimes if (*p->flags&ISO_SUSP_TSTAMP_CREAT) 374df8bae1dSRodney W. Grimes ptime += 17; 375df8bae1dSRodney W. Grimes 376df8bae1dSRodney W. Grimes if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) { 377df8bae1dSRodney W. Grimes cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_mtime); 378df8bae1dSRodney W. Grimes ptime += 17; 379df8bae1dSRodney W. Grimes } else 3801dbaf90cSBruce Evans bzero(&ana->inop->inode.iso_mtime,sizeof(struct timespec)); 381df8bae1dSRodney W. Grimes 382df8bae1dSRodney W. Grimes if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) { 383df8bae1dSRodney W. Grimes cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_atime); 384df8bae1dSRodney W. Grimes ptime += 17; 385df8bae1dSRodney W. Grimes } else 386df8bae1dSRodney W. Grimes ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime; 387df8bae1dSRodney W. Grimes 388df8bae1dSRodney W. Grimes if (*p->flags&ISO_SUSP_TSTAMP_ATTR) 389df8bae1dSRodney W. Grimes cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_ctime); 390df8bae1dSRodney W. Grimes else 391df8bae1dSRodney W. Grimes ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime; 392df8bae1dSRodney W. Grimes 393df8bae1dSRodney W. Grimes } 394df8bae1dSRodney W. Grimes ana->fields &= ~ISO_SUSP_TSTAMP; 395df8bae1dSRodney W. Grimes return ISO_SUSP_TSTAMP; 396df8bae1dSRodney W. Grimes } 397df8bae1dSRodney W. Grimes 398df8bae1dSRodney W. Grimes static void 399df8bae1dSRodney W. Grimes cd9660_rrip_deftstamp(isodir,ana) 400df8bae1dSRodney W. Grimes struct iso_directory_record *isodir; 401df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 402df8bae1dSRodney W. Grimes { 403988fa8efSJoerg Wunsch cd9660_deftstamp(isodir,ana->inop,NULL,ISO_FTYPE_RRIP); 404df8bae1dSRodney W. Grimes } 405df8bae1dSRodney W. Grimes 406df8bae1dSRodney W. Grimes /* 407df8bae1dSRodney W. Grimes * POSIX device modes 408df8bae1dSRodney W. Grimes */ 409df8bae1dSRodney W. Grimes static int 410df8bae1dSRodney W. Grimes cd9660_rrip_device(p,ana) 411df8bae1dSRodney W. Grimes ISO_RRIP_DEVICE *p; 412df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 413df8bae1dSRodney W. Grimes { 414996c772fSJohn Dyson u_int high, low; 415df8bae1dSRodney W. Grimes 416996c772fSJohn Dyson high = isonum_733(p->dev_t_high); 417996c772fSJohn Dyson low = isonum_733(p->dev_t_low); 418df8bae1dSRodney W. Grimes 419996c772fSJohn Dyson if (high == 0) 420a4611ab6SEd Schouten ana->inop->inode.iso_rdev = makedev(major(low), minor(low)); 421996c772fSJohn Dyson else 422a4611ab6SEd Schouten ana->inop->inode.iso_rdev = makedev(high, minor(low)); 423df8bae1dSRodney W. Grimes ana->fields &= ~ISO_SUSP_DEVICE; 424df8bae1dSRodney W. Grimes return ISO_SUSP_DEVICE; 425df8bae1dSRodney W. Grimes } 426df8bae1dSRodney W. Grimes 427df8bae1dSRodney W. Grimes /* 428df8bae1dSRodney W. Grimes * Flag indicating 429df8bae1dSRodney W. Grimes */ 430df8bae1dSRodney W. Grimes static int 431df8bae1dSRodney W. Grimes cd9660_rrip_idflag(p,ana) 432df8bae1dSRodney W. Grimes ISO_RRIP_IDFLAG *p; 433df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 434df8bae1dSRodney W. Grimes { 435df8bae1dSRodney W. Grimes ana->fields &= isonum_711(p->flags)|~0xff; /* don't touch high bits */ 436df8bae1dSRodney W. Grimes /* special handling of RE field */ 437df8bae1dSRodney W. Grimes if (ana->fields&ISO_SUSP_RELDIR) 43810dd32cdSBruce Evans return cd9660_rrip_reldir(/* XXX */ (ISO_RRIP_RELDIR *)p,ana); 439df8bae1dSRodney W. Grimes 440df8bae1dSRodney W. Grimes return ISO_SUSP_IDFLAG; 441df8bae1dSRodney W. Grimes } 442df8bae1dSRodney W. Grimes 443df8bae1dSRodney W. Grimes /* 444df8bae1dSRodney W. Grimes * Continuation pointer 445df8bae1dSRodney W. Grimes */ 446df8bae1dSRodney W. Grimes static int 447df8bae1dSRodney W. Grimes cd9660_rrip_cont(p,ana) 448df8bae1dSRodney W. Grimes ISO_RRIP_CONT *p; 449df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 450df8bae1dSRodney W. Grimes { 451df8bae1dSRodney W. Grimes ana->iso_ce_blk = isonum_733(p->location); 452df8bae1dSRodney W. Grimes ana->iso_ce_off = isonum_733(p->offset); 453df8bae1dSRodney W. Grimes ana->iso_ce_len = isonum_733(p->length); 454df8bae1dSRodney W. Grimes return ISO_SUSP_CONT; 455df8bae1dSRodney W. Grimes } 456df8bae1dSRodney W. Grimes 457df8bae1dSRodney W. Grimes /* 458df8bae1dSRodney W. Grimes * System Use end 459df8bae1dSRodney W. Grimes */ 460df8bae1dSRodney W. Grimes static int 461df8bae1dSRodney W. Grimes cd9660_rrip_stop(p,ana) 462df8bae1dSRodney W. Grimes ISO_SUSP_HEADER *p; 463df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 464df8bae1dSRodney W. Grimes { 465df8bae1dSRodney W. Grimes return ISO_SUSP_STOP; 466df8bae1dSRodney W. Grimes } 467df8bae1dSRodney W. Grimes 468df8bae1dSRodney W. Grimes /* 469df8bae1dSRodney W. Grimes * Extension reference 470df8bae1dSRodney W. Grimes */ 471df8bae1dSRodney W. Grimes static int 472df8bae1dSRodney W. Grimes cd9660_rrip_extref(p,ana) 473df8bae1dSRodney W. Grimes ISO_RRIP_EXTREF *p; 474df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 475df8bae1dSRodney W. Grimes { 476f7b8cfa8SUlf Lilleengen if ( ! ((isonum_711(p->len_id) == 10 477f7b8cfa8SUlf Lilleengen && bcmp((char *)p + 8,"RRIP_1991A",10) == 0) 478f7b8cfa8SUlf Lilleengen || (isonum_711(p->len_id) == 10 479f7b8cfa8SUlf Lilleengen && bcmp((char *)p + 8,"IEEE_P1282",10) == 0) 480f7b8cfa8SUlf Lilleengen || (isonum_711(p->len_id) == 9 481f7b8cfa8SUlf Lilleengen && bcmp((char *)p + 8,"IEEE_1282", 9) == 0)) 482df8bae1dSRodney W. Grimes || isonum_711(p->version) != 1) 483df8bae1dSRodney W. Grimes return 0; 484df8bae1dSRodney W. Grimes ana->fields &= ~ISO_SUSP_EXTREF; 485df8bae1dSRodney W. Grimes return ISO_SUSP_EXTREF; 486df8bae1dSRodney W. Grimes } 487df8bae1dSRodney W. Grimes 488df8bae1dSRodney W. Grimes static int 489df8bae1dSRodney W. Grimes cd9660_rrip_loop(isodir,ana,table) 490df8bae1dSRodney W. Grimes struct iso_directory_record *isodir; 491df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE *ana; 492df8bae1dSRodney W. Grimes RRIP_TABLE *table; 493df8bae1dSRodney W. Grimes { 494bffd1b7aSPoul-Henning Kamp RRIP_TABLE *ptable; 495bffd1b7aSPoul-Henning Kamp ISO_SUSP_HEADER *phead; 496bffd1b7aSPoul-Henning Kamp ISO_SUSP_HEADER *pend; 497df8bae1dSRodney W. Grimes struct buf *bp = NULL; 498df8bae1dSRodney W. Grimes char *pwhead; 499c4f02a89SMax Khon u_short c; 500df8bae1dSRodney W. Grimes int result; 501df8bae1dSRodney W. Grimes 502df8bae1dSRodney W. Grimes /* 503df8bae1dSRodney W. Grimes * Note: If name length is odd, 504df8bae1dSRodney W. Grimes * it will be padding 1 byte after the name 505df8bae1dSRodney W. Grimes */ 506df8bae1dSRodney W. Grimes pwhead = isodir->name + isonum_711(isodir->name_len); 507df8bae1dSRodney W. Grimes if (!(isonum_711(isodir->name_len)&1)) 508df8bae1dSRodney W. Grimes pwhead++; 509c4f02a89SMax Khon isochar(isodir->name, pwhead, ana->imp->joliet_level, &c, NULL, 510c4f02a89SMax Khon ana->imp->im_flags, ana->imp->im_d2l); 511df8bae1dSRodney W. Grimes 512df8bae1dSRodney W. Grimes /* If it's not the '.' entry of the root dir obey SP field */ 51344e568e2SDaniel C. Sobral if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent) 514df8bae1dSRodney W. Grimes pwhead += ana->imp->rr_skip; 515df8bae1dSRodney W. Grimes else 516df8bae1dSRodney W. Grimes pwhead += ana->imp->rr_skip0; 517df8bae1dSRodney W. Grimes 518df8bae1dSRodney W. Grimes phead = (ISO_SUSP_HEADER *)pwhead; 519df8bae1dSRodney W. Grimes pend = (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length)); 520df8bae1dSRodney W. Grimes 521df8bae1dSRodney W. Grimes result = 0; 522df8bae1dSRodney W. Grimes while (1) { 523df8bae1dSRodney W. Grimes ana->iso_ce_len = 0; 524df8bae1dSRodney W. Grimes /* 525df8bae1dSRodney W. Grimes * Note: "pend" should be more than one SUSP header 526df8bae1dSRodney W. Grimes */ 527df8bae1dSRodney W. Grimes while (pend >= phead + 1) { 528df8bae1dSRodney W. Grimes if (isonum_711(phead->version) == 1) { 529df8bae1dSRodney W. Grimes for (ptable = table; ptable->func; ptable++) { 530df8bae1dSRodney W. Grimes if (*phead->type == *ptable->type 531df8bae1dSRodney W. Grimes && phead->type[1] == ptable->type[1]) { 532df8bae1dSRodney W. Grimes result |= ptable->func(phead,ana); 533df8bae1dSRodney W. Grimes break; 534df8bae1dSRodney W. Grimes } 535df8bae1dSRodney W. Grimes } 536df8bae1dSRodney W. Grimes if (!ana->fields) 537df8bae1dSRodney W. Grimes break; 538df8bae1dSRodney W. Grimes } 539996c772fSJohn Dyson if (result&ISO_SUSP_STOP) { 540996c772fSJohn Dyson result &= ~ISO_SUSP_STOP; 541996c772fSJohn Dyson break; 542996c772fSJohn Dyson } 543996c772fSJohn Dyson /* plausibility check */ 544996c772fSJohn Dyson if (isonum_711(phead->length) < sizeof(*phead)) 545996c772fSJohn Dyson break; 546df8bae1dSRodney W. Grimes /* 547df8bae1dSRodney W. Grimes * move to next SUSP 548df8bae1dSRodney W. Grimes * Hopefully this works with newer versions, too 549df8bae1dSRodney W. Grimes */ 550df8bae1dSRodney W. Grimes phead = (ISO_SUSP_HEADER *)((char *)phead + isonum_711(phead->length)); 551df8bae1dSRodney W. Grimes } 552df8bae1dSRodney W. Grimes 553df8bae1dSRodney W. Grimes if (ana->fields && ana->iso_ce_len) { 554df8bae1dSRodney W. Grimes if (ana->iso_ce_blk >= ana->imp->volume_space_size 555df8bae1dSRodney W. Grimes || ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size 556df8bae1dSRodney W. Grimes || bread(ana->imp->im_devvp, 557996c772fSJohn Dyson ana->iso_ce_blk << 558996c772fSJohn Dyson (ana->imp->im_bshift - DEV_BSHIFT), 559df8bae1dSRodney W. Grimes ana->imp->logical_block_size, NOCRED, &bp)) 560df8bae1dSRodney W. Grimes /* what to do now? */ 561df8bae1dSRodney W. Grimes break; 562996c772fSJohn Dyson phead = (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off); 563df8bae1dSRodney W. Grimes pend = (ISO_SUSP_HEADER *) ((char *)phead + ana->iso_ce_len); 564df8bae1dSRodney W. Grimes } else 565df8bae1dSRodney W. Grimes break; 566df8bae1dSRodney W. Grimes } 567df8bae1dSRodney W. Grimes if (bp) 568df8bae1dSRodney W. Grimes brelse(bp); 569df8bae1dSRodney W. Grimes /* 570df8bae1dSRodney W. Grimes * If we don't find the Basic SUSP stuffs, just set default value 571df8bae1dSRodney W. Grimes * (attribute/time stamp) 572df8bae1dSRodney W. Grimes */ 573df8bae1dSRodney W. Grimes for (ptable = table; ptable->func2; ptable++) 574df8bae1dSRodney W. Grimes if (!(ptable->result&result)) 575df8bae1dSRodney W. Grimes ptable->func2(isodir,ana); 576df8bae1dSRodney W. Grimes 577df8bae1dSRodney W. Grimes return result; 578df8bae1dSRodney W. Grimes } 579df8bae1dSRodney W. Grimes 58010dd32cdSBruce Evans /* 581996c772fSJohn Dyson * Get Attributes. 582996c772fSJohn Dyson */ 583996c772fSJohn Dyson /* 58410dd32cdSBruce Evans * XXX the casts are bogus but will do for now. 58510dd32cdSBruce Evans */ 58610dd32cdSBruce Evans #define BC (rrt_func_t *) 587df8bae1dSRodney W. Grimes static RRIP_TABLE rrip_table_analyze[] = { 58810dd32cdSBruce Evans { "PX", BC cd9660_rrip_attr, cd9660_rrip_defattr, ISO_SUSP_ATTR }, 58910dd32cdSBruce Evans { "TF", BC cd9660_rrip_tstamp, cd9660_rrip_deftstamp, ISO_SUSP_TSTAMP }, 59010dd32cdSBruce Evans { "PN", BC cd9660_rrip_device, 0, ISO_SUSP_DEVICE }, 59110dd32cdSBruce Evans { "RR", BC cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG }, 59210dd32cdSBruce Evans { "CE", BC cd9660_rrip_cont, 0, ISO_SUSP_CONT }, 59310dd32cdSBruce Evans { "ST", BC cd9660_rrip_stop, 0, ISO_SUSP_STOP }, 594df8bae1dSRodney W. Grimes { "", 0, 0, 0 } 595df8bae1dSRodney W. Grimes }; 596df8bae1dSRodney W. Grimes 597df8bae1dSRodney W. Grimes int 598df8bae1dSRodney W. Grimes cd9660_rrip_analyze(isodir,inop,imp) 599df8bae1dSRodney W. Grimes struct iso_directory_record *isodir; 600df8bae1dSRodney W. Grimes struct iso_node *inop; 601df8bae1dSRodney W. Grimes struct iso_mnt *imp; 602df8bae1dSRodney W. Grimes { 603df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE analyze; 604df8bae1dSRodney W. Grimes 605df8bae1dSRodney W. Grimes analyze.inop = inop; 606df8bae1dSRodney W. Grimes analyze.imp = imp; 607df8bae1dSRodney W. Grimes analyze.fields = ISO_SUSP_ATTR|ISO_SUSP_TSTAMP|ISO_SUSP_DEVICE; 608df8bae1dSRodney W. Grimes 609df8bae1dSRodney W. Grimes return cd9660_rrip_loop(isodir,&analyze,rrip_table_analyze); 610df8bae1dSRodney W. Grimes } 611df8bae1dSRodney W. Grimes 612df8bae1dSRodney W. Grimes /* 613996c772fSJohn Dyson * Get Alternate Name. 614df8bae1dSRodney W. Grimes */ 615df8bae1dSRodney W. Grimes static RRIP_TABLE rrip_table_getname[] = { 61610dd32cdSBruce Evans { "NM", BC cd9660_rrip_altname, cd9660_rrip_defname, ISO_SUSP_ALTNAME }, 61710dd32cdSBruce Evans { "CL", BC cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK }, 61810dd32cdSBruce Evans { "PL", BC cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK }, 61910dd32cdSBruce Evans { "RE", BC cd9660_rrip_reldir, 0, ISO_SUSP_RELDIR }, 62010dd32cdSBruce Evans { "RR", BC cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG }, 62110dd32cdSBruce Evans { "CE", BC cd9660_rrip_cont, 0, ISO_SUSP_CONT }, 62210dd32cdSBruce Evans { "ST", BC cd9660_rrip_stop, 0, ISO_SUSP_STOP }, 623df8bae1dSRodney W. Grimes { "", 0, 0, 0 } 624df8bae1dSRodney W. Grimes }; 625df8bae1dSRodney W. Grimes 626df8bae1dSRodney W. Grimes int 627df8bae1dSRodney W. Grimes cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp) 628df8bae1dSRodney W. Grimes struct iso_directory_record *isodir; 629df8bae1dSRodney W. Grimes char *outbuf; 630df8bae1dSRodney W. Grimes u_short *outlen; 631df8bae1dSRodney W. Grimes ino_t *inump; 632df8bae1dSRodney W. Grimes struct iso_mnt *imp; 633df8bae1dSRodney W. Grimes { 634df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE analyze; 635df8bae1dSRodney W. Grimes RRIP_TABLE *tab; 636c4f02a89SMax Khon u_short c; 637df8bae1dSRodney W. Grimes 638df8bae1dSRodney W. Grimes analyze.outbuf = outbuf; 639df8bae1dSRodney W. Grimes analyze.outlen = outlen; 640df8bae1dSRodney W. Grimes analyze.maxlen = NAME_MAX; 641df8bae1dSRodney W. Grimes analyze.inump = inump; 642df8bae1dSRodney W. Grimes analyze.imp = imp; 643df8bae1dSRodney W. Grimes analyze.fields = ISO_SUSP_ALTNAME|ISO_SUSP_RELDIR|ISO_SUSP_CLINK|ISO_SUSP_PLINK; 644df8bae1dSRodney W. Grimes *outlen = 0; 645df8bae1dSRodney W. Grimes 64644e568e2SDaniel C. Sobral isochar(isodir->name, isodir->name + isonum_711(isodir->name_len), 647c4f02a89SMax Khon imp->joliet_level, &c, NULL, imp->im_flags, imp->im_d2l); 648df8bae1dSRodney W. Grimes tab = rrip_table_getname; 64944e568e2SDaniel C. Sobral if (c == 0 || c == 1) { 650df8bae1dSRodney W. Grimes cd9660_rrip_defname(isodir,&analyze); 651df8bae1dSRodney W. Grimes 652df8bae1dSRodney W. Grimes analyze.fields &= ~ISO_SUSP_ALTNAME; 653df8bae1dSRodney W. Grimes tab++; 654df8bae1dSRodney W. Grimes } 655df8bae1dSRodney W. Grimes 656df8bae1dSRodney W. Grimes return cd9660_rrip_loop(isodir,&analyze,tab); 657df8bae1dSRodney W. Grimes } 658df8bae1dSRodney W. Grimes 659df8bae1dSRodney W. Grimes /* 660996c772fSJohn Dyson * Get Symbolic Link. 661df8bae1dSRodney W. Grimes */ 662df8bae1dSRodney W. Grimes static RRIP_TABLE rrip_table_getsymname[] = { 66310dd32cdSBruce Evans { "SL", BC cd9660_rrip_slink, 0, ISO_SUSP_SLINK }, 66410dd32cdSBruce Evans { "RR", BC cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG }, 66510dd32cdSBruce Evans { "CE", BC cd9660_rrip_cont, 0, ISO_SUSP_CONT }, 66610dd32cdSBruce Evans { "ST", BC cd9660_rrip_stop, 0, ISO_SUSP_STOP }, 667df8bae1dSRodney W. Grimes { "", 0, 0, 0 } 668df8bae1dSRodney W. Grimes }; 669df8bae1dSRodney W. Grimes 670df8bae1dSRodney W. Grimes int 671df8bae1dSRodney W. Grimes cd9660_rrip_getsymname(isodir,outbuf,outlen,imp) 672df8bae1dSRodney W. Grimes struct iso_directory_record *isodir; 673df8bae1dSRodney W. Grimes char *outbuf; 674df8bae1dSRodney W. Grimes u_short *outlen; 675df8bae1dSRodney W. Grimes struct iso_mnt *imp; 676df8bae1dSRodney W. Grimes { 677df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE analyze; 678df8bae1dSRodney W. Grimes 679df8bae1dSRodney W. Grimes analyze.outbuf = outbuf; 680df8bae1dSRodney W. Grimes analyze.outlen = outlen; 681df8bae1dSRodney W. Grimes *outlen = 0; 682df8bae1dSRodney W. Grimes analyze.maxlen = MAXPATHLEN; 683df8bae1dSRodney W. Grimes analyze.cont = 1; /* don't start with a slash */ 684df8bae1dSRodney W. Grimes analyze.imp = imp; 685df8bae1dSRodney W. Grimes analyze.fields = ISO_SUSP_SLINK; 686df8bae1dSRodney W. Grimes 687df8bae1dSRodney W. Grimes return (cd9660_rrip_loop(isodir,&analyze,rrip_table_getsymname)&ISO_SUSP_SLINK); 688df8bae1dSRodney W. Grimes } 689df8bae1dSRodney W. Grimes 690df8bae1dSRodney W. Grimes static RRIP_TABLE rrip_table_extref[] = { 69110dd32cdSBruce Evans { "ER", BC cd9660_rrip_extref, 0, ISO_SUSP_EXTREF }, 69210dd32cdSBruce Evans { "CE", BC cd9660_rrip_cont, 0, ISO_SUSP_CONT }, 69310dd32cdSBruce Evans { "ST", BC cd9660_rrip_stop, 0, ISO_SUSP_STOP }, 694df8bae1dSRodney W. Grimes { "", 0, 0, 0 } 695df8bae1dSRodney W. Grimes }; 696df8bae1dSRodney W. Grimes 697df8bae1dSRodney W. Grimes /* 698df8bae1dSRodney W. Grimes * Check for Rock Ridge Extension and return offset of its fields. 699996c772fSJohn Dyson * Note: We insist on the ER field. 700df8bae1dSRodney W. Grimes */ 701df8bae1dSRodney W. Grimes int 702df8bae1dSRodney W. Grimes cd9660_rrip_offset(isodir,imp) 703df8bae1dSRodney W. Grimes struct iso_directory_record *isodir; 704df8bae1dSRodney W. Grimes struct iso_mnt *imp; 705df8bae1dSRodney W. Grimes { 706df8bae1dSRodney W. Grimes ISO_RRIP_OFFSET *p; 707df8bae1dSRodney W. Grimes ISO_RRIP_ANALYZE analyze; 708df8bae1dSRodney W. Grimes 709df8bae1dSRodney W. Grimes imp->rr_skip0 = 0; 710df8bae1dSRodney W. Grimes p = (ISO_RRIP_OFFSET *)(isodir->name + 1); 711df8bae1dSRodney W. Grimes if (bcmp(p,"SP\7\1\276\357",6)) { 712df8bae1dSRodney W. Grimes /* Maybe, it's a CDROM XA disc? */ 713df8bae1dSRodney W. Grimes imp->rr_skip0 = 15; 714df8bae1dSRodney W. Grimes p = (ISO_RRIP_OFFSET *)((char *)p + 15); 715df8bae1dSRodney W. Grimes if (bcmp(p,"SP\7\1\276\357",6)) 716df8bae1dSRodney W. Grimes return -1; 717df8bae1dSRodney W. Grimes } 718df8bae1dSRodney W. Grimes 719df8bae1dSRodney W. Grimes analyze.imp = imp; 720df8bae1dSRodney W. Grimes analyze.fields = ISO_SUSP_EXTREF; 721df8bae1dSRodney W. Grimes if (!(cd9660_rrip_loop(isodir,&analyze,rrip_table_extref)&ISO_SUSP_EXTREF)) 722df8bae1dSRodney W. Grimes return -1; 723df8bae1dSRodney W. Grimes 724df8bae1dSRodney W. Grimes return isonum_711(p->skip); 725df8bae1dSRodney W. Grimes } 726