1*65789Smckusick /*- 2*65789Smckusick * Copyright (c) 1993, 1994 3*65789Smckusick * The Regents of the University of California. All rights reserved. 4*65789Smckusick * 5*65789Smckusick * This code is derived from software contributed to Berkeley 6*65789Smckusick * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension 7*65789Smckusick * Support code is derived from software contributed to Berkeley 8*65789Smckusick * by Atsushi Murai (amurai@spec.co.jp). 9*65789Smckusick * 10*65789Smckusick * %sccs.include.redist.c% 11*65789Smckusick * 12*65789Smckusick * @(#)cd9660_rrip.c 8.1 (Berkeley) 01/21/94 13*65789Smckusick */ 14*65789Smckusick 15*65789Smckusick #include <sys/param.h> 16*65789Smckusick #include <sys/namei.h> 17*65789Smckusick #include <sys/buf.h> 18*65789Smckusick #include <sys/file.h> 19*65789Smckusick #include <sys/vnode.h> 20*65789Smckusick #include <sys/mount.h> 21*65789Smckusick #include <sys/kernel.h> 22*65789Smckusick #include <sys/stat.h> 23*65789Smckusick #include <sys/types.h> 24*65789Smckusick 25*65789Smckusick #include <sys/time.h> 26*65789Smckusick 27*65789Smckusick #include <isofs/cd9660/iso.h> 28*65789Smckusick #include <isofs/cd9660/isofs_node.h> 29*65789Smckusick #include <isofs/cd9660/isofs_rrip.h> 30*65789Smckusick #include <isofs/cd9660/iso_rrip.h> 31*65789Smckusick 32*65789Smckusick /* 33*65789Smckusick * POSIX file attribute 34*65789Smckusick */ 35*65789Smckusick static int 36*65789Smckusick isofs_rrip_attr(p,ana) 37*65789Smckusick ISO_RRIP_ATTR *p; 38*65789Smckusick ISO_RRIP_ANALYZE *ana; 39*65789Smckusick { 40*65789Smckusick ana->inop->inode.iso_mode = isonum_731(p->mode_l); 41*65789Smckusick ana->inop->inode.iso_uid = (uid_t)isonum_731(p->uid_l); 42*65789Smckusick ana->inop->inode.iso_gid = (gid_t)isonum_731(p->gid_l); 43*65789Smckusick ana->inop->inode.iso_links = isonum_731(p->links_l); 44*65789Smckusick ana->fields &= ~ISO_SUSP_ATTR; 45*65789Smckusick return ISO_SUSP_ATTR; 46*65789Smckusick } 47*65789Smckusick 48*65789Smckusick static void 49*65789Smckusick isofs_rrip_defattr(isodir,ana) 50*65789Smckusick struct iso_directory_record *isodir; 51*65789Smckusick ISO_RRIP_ANALYZE *ana; 52*65789Smckusick { 53*65789Smckusick /* But this is a required field! */ 54*65789Smckusick printf("RRIP without PX field?\n"); 55*65789Smckusick isofs_defattr(isodir,ana->inop,NULL); 56*65789Smckusick } 57*65789Smckusick 58*65789Smckusick /* 59*65789Smckusick * Symbolic Links 60*65789Smckusick */ 61*65789Smckusick static int 62*65789Smckusick isofs_rrip_slink(p,ana) 63*65789Smckusick ISO_RRIP_SLINK *p; 64*65789Smckusick ISO_RRIP_ANALYZE *ana; 65*65789Smckusick { 66*65789Smckusick register ISO_RRIP_SLINK_COMPONENT *pcomp; 67*65789Smckusick register ISO_RRIP_SLINK_COMPONENT *pcompe; 68*65789Smckusick int len, wlen, cont; 69*65789Smckusick char *outbuf, *inbuf; 70*65789Smckusick 71*65789Smckusick pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component; 72*65789Smckusick pcompe = (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length)); 73*65789Smckusick len = *ana->outlen; 74*65789Smckusick outbuf = ana->outbuf; 75*65789Smckusick cont = ana->cont; 76*65789Smckusick 77*65789Smckusick /* 78*65789Smckusick * Gathering a Symbolic name from each component with path 79*65789Smckusick */ 80*65789Smckusick for (; 81*65789Smckusick pcomp < pcompe; 82*65789Smckusick pcomp = (ISO_RRIP_SLINK_COMPONENT *)((char *)pcomp + ISO_RRIP_SLSIZ 83*65789Smckusick + isonum_711(pcomp->clen))) { 84*65789Smckusick 85*65789Smckusick if (!cont) { 86*65789Smckusick if (len < ana->maxlen) { 87*65789Smckusick len++; 88*65789Smckusick *outbuf++ = '/'; 89*65789Smckusick } 90*65789Smckusick } 91*65789Smckusick cont = 0; 92*65789Smckusick 93*65789Smckusick inbuf = ".."; 94*65789Smckusick wlen = 0; 95*65789Smckusick 96*65789Smckusick switch (*pcomp->cflag) { 97*65789Smckusick 98*65789Smckusick case ISO_SUSP_CFLAG_CURRENT: 99*65789Smckusick /* Inserting Current */ 100*65789Smckusick wlen = 1; 101*65789Smckusick break; 102*65789Smckusick 103*65789Smckusick case ISO_SUSP_CFLAG_PARENT: 104*65789Smckusick /* Inserting Parent */ 105*65789Smckusick wlen = 2; 106*65789Smckusick break; 107*65789Smckusick 108*65789Smckusick case ISO_SUSP_CFLAG_ROOT: 109*65789Smckusick /* Inserting slash for ROOT */ 110*65789Smckusick /* start over from beginning(?) */ 111*65789Smckusick outbuf -= len; 112*65789Smckusick len = 0; 113*65789Smckusick break; 114*65789Smckusick 115*65789Smckusick case ISO_SUSP_CFLAG_VOLROOT: 116*65789Smckusick /* Inserting a mount point i.e. "/cdrom" */ 117*65789Smckusick /* same as above */ 118*65789Smckusick outbuf -= len; 119*65789Smckusick len = 0; 120*65789Smckusick inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname; 121*65789Smckusick wlen = strlen(inbuf); 122*65789Smckusick break; 123*65789Smckusick 124*65789Smckusick case ISO_SUSP_CFLAG_HOST: 125*65789Smckusick /* Inserting hostname i.e. "kurt.tools.de" */ 126*65789Smckusick inbuf = hostname; 127*65789Smckusick wlen = hostnamelen; 128*65789Smckusick break; 129*65789Smckusick 130*65789Smckusick case ISO_SUSP_CFLAG_CONTINUE: 131*65789Smckusick cont = 1; 132*65789Smckusick /* fall thru */ 133*65789Smckusick case 0: 134*65789Smckusick /* Inserting component */ 135*65789Smckusick wlen = isonum_711(pcomp->clen); 136*65789Smckusick inbuf = pcomp->name; 137*65789Smckusick break; 138*65789Smckusick default: 139*65789Smckusick printf("RRIP with incorrect flags?"); 140*65789Smckusick wlen = ana->maxlen + 1; 141*65789Smckusick break; 142*65789Smckusick } 143*65789Smckusick 144*65789Smckusick if (len + wlen > ana->maxlen) { 145*65789Smckusick /* indicate error to caller */ 146*65789Smckusick ana->cont = 1; 147*65789Smckusick ana->fields = 0; 148*65789Smckusick ana->outbuf -= *ana->outlen; 149*65789Smckusick *ana->outlen = 0; 150*65789Smckusick return 0; 151*65789Smckusick } 152*65789Smckusick 153*65789Smckusick bcopy(inbuf,outbuf,wlen); 154*65789Smckusick outbuf += wlen; 155*65789Smckusick len += wlen; 156*65789Smckusick 157*65789Smckusick } 158*65789Smckusick ana->outbuf = outbuf; 159*65789Smckusick *ana->outlen = len; 160*65789Smckusick ana->cont = cont; 161*65789Smckusick 162*65789Smckusick if (!isonum_711(p->flags)) { 163*65789Smckusick ana->fields &= ~ISO_SUSP_SLINK; 164*65789Smckusick return ISO_SUSP_SLINK; 165*65789Smckusick } 166*65789Smckusick return 0; 167*65789Smckusick } 168*65789Smckusick 169*65789Smckusick /* 170*65789Smckusick * Alternate name 171*65789Smckusick */ 172*65789Smckusick static int 173*65789Smckusick isofs_rrip_altname(p,ana) 174*65789Smckusick ISO_RRIP_ALTNAME *p; 175*65789Smckusick ISO_RRIP_ANALYZE *ana; 176*65789Smckusick { 177*65789Smckusick char *inbuf; 178*65789Smckusick int wlen; 179*65789Smckusick int cont; 180*65789Smckusick 181*65789Smckusick inbuf = ".."; 182*65789Smckusick wlen = 0; 183*65789Smckusick cont = 0; 184*65789Smckusick 185*65789Smckusick switch (*p->flags) { 186*65789Smckusick case ISO_SUSP_CFLAG_CURRENT: 187*65789Smckusick /* Inserting Current */ 188*65789Smckusick wlen = 1; 189*65789Smckusick break; 190*65789Smckusick 191*65789Smckusick case ISO_SUSP_CFLAG_PARENT: 192*65789Smckusick /* Inserting Parent */ 193*65789Smckusick wlen = 2; 194*65789Smckusick break; 195*65789Smckusick 196*65789Smckusick case ISO_SUSP_CFLAG_HOST: 197*65789Smckusick /* Inserting hostname i.e. "kurt.tools.de" */ 198*65789Smckusick inbuf = hostname; 199*65789Smckusick wlen = hostnamelen; 200*65789Smckusick break; 201*65789Smckusick 202*65789Smckusick case ISO_SUSP_CFLAG_CONTINUE: 203*65789Smckusick cont = 1; 204*65789Smckusick /* fall thru */ 205*65789Smckusick case 0: 206*65789Smckusick /* Inserting component */ 207*65789Smckusick wlen = isonum_711(p->h.length) - 5; 208*65789Smckusick inbuf = (char *)p + 5; 209*65789Smckusick break; 210*65789Smckusick 211*65789Smckusick default: 212*65789Smckusick printf("RRIP with incorrect NM flags?\n"); 213*65789Smckusick wlen = ana->maxlen + 1; 214*65789Smckusick break; 215*65789Smckusick } 216*65789Smckusick 217*65789Smckusick if ((*ana->outlen += wlen) > ana->maxlen) { 218*65789Smckusick /* treat as no name field */ 219*65789Smckusick ana->fields &= ~ISO_SUSP_ALTNAME; 220*65789Smckusick ana->outbuf -= *ana->outlen - wlen; 221*65789Smckusick *ana->outlen = 0; 222*65789Smckusick return 0; 223*65789Smckusick } 224*65789Smckusick 225*65789Smckusick bcopy(inbuf,ana->outbuf,wlen); 226*65789Smckusick ana->outbuf += wlen; 227*65789Smckusick 228*65789Smckusick if (!cont) { 229*65789Smckusick ana->fields &= ~ISO_SUSP_ALTNAME; 230*65789Smckusick return ISO_SUSP_ALTNAME; 231*65789Smckusick } 232*65789Smckusick return 0; 233*65789Smckusick } 234*65789Smckusick 235*65789Smckusick static void 236*65789Smckusick isofs_rrip_defname(isodir,ana) 237*65789Smckusick struct iso_directory_record *isodir; 238*65789Smckusick ISO_RRIP_ANALYZE *ana; 239*65789Smckusick { 240*65789Smckusick strcpy(ana->outbuf,".."); 241*65789Smckusick switch (*isodir->name) { 242*65789Smckusick default: 243*65789Smckusick isofntrans(isodir->name,isonum_711(isodir->name_len), 244*65789Smckusick ana->outbuf,ana->outlen, 245*65789Smckusick 1,isonum_711(isodir->flags)&4); 246*65789Smckusick break; 247*65789Smckusick case 0: 248*65789Smckusick *ana->outlen = 1; 249*65789Smckusick break; 250*65789Smckusick case 1: 251*65789Smckusick *ana->outlen = 2; 252*65789Smckusick break; 253*65789Smckusick } 254*65789Smckusick } 255*65789Smckusick 256*65789Smckusick /* 257*65789Smckusick * Parent or Child Link 258*65789Smckusick */ 259*65789Smckusick static int 260*65789Smckusick isofs_rrip_pclink(p,ana) 261*65789Smckusick ISO_RRIP_CLINK *p; 262*65789Smckusick ISO_RRIP_ANALYZE *ana; 263*65789Smckusick { 264*65789Smckusick *ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift; 265*65789Smckusick ana->fields &= ~(ISO_SUSP_CLINK|ISO_SUSP_PLINK); 266*65789Smckusick return *p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK; 267*65789Smckusick } 268*65789Smckusick 269*65789Smckusick /* 270*65789Smckusick * Relocated directory 271*65789Smckusick */ 272*65789Smckusick static int 273*65789Smckusick isofs_rrip_reldir(p,ana) 274*65789Smckusick ISO_RRIP_RELDIR *p; 275*65789Smckusick ISO_RRIP_ANALYZE *ana; 276*65789Smckusick { 277*65789Smckusick /* special hack to make caller aware of RE field */ 278*65789Smckusick *ana->outlen = 0; 279*65789Smckusick ana->fields = 0; 280*65789Smckusick return ISO_SUSP_RELDIR|ISO_SUSP_ALTNAME|ISO_SUSP_CLINK|ISO_SUSP_PLINK; 281*65789Smckusick } 282*65789Smckusick 283*65789Smckusick static int 284*65789Smckusick isofs_rrip_tstamp(p,ana) 285*65789Smckusick ISO_RRIP_TSTAMP *p; 286*65789Smckusick ISO_RRIP_ANALYZE *ana; 287*65789Smckusick { 288*65789Smckusick unsigned char *ptime; 289*65789Smckusick 290*65789Smckusick ptime = p->time; 291*65789Smckusick 292*65789Smckusick /* Check a format of time stamp (7bytes/17bytes) */ 293*65789Smckusick if (!(*p->flags&ISO_SUSP_TSTAMP_FORM17)) { 294*65789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_CREAT) 295*65789Smckusick ptime += 7; 296*65789Smckusick 297*65789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) { 298*65789Smckusick isofs_tstamp_conv7(ptime,&ana->inop->inode.iso_mtime); 299*65789Smckusick ptime += 7; 300*65789Smckusick } else 301*65789Smckusick bzero(&ana->inop->inode.iso_mtime,sizeof(struct timeval)); 302*65789Smckusick 303*65789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) { 304*65789Smckusick isofs_tstamp_conv7(ptime,&ana->inop->inode.iso_atime); 305*65789Smckusick ptime += 7; 306*65789Smckusick } else 307*65789Smckusick ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime; 308*65789Smckusick 309*65789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_ATTR) 310*65789Smckusick isofs_tstamp_conv7(ptime,&ana->inop->inode.iso_ctime); 311*65789Smckusick else 312*65789Smckusick ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime; 313*65789Smckusick 314*65789Smckusick } else { 315*65789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_CREAT) 316*65789Smckusick ptime += 17; 317*65789Smckusick 318*65789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) { 319*65789Smckusick isofs_tstamp_conv17(ptime,&ana->inop->inode.iso_mtime); 320*65789Smckusick ptime += 17; 321*65789Smckusick } else 322*65789Smckusick bzero(&ana->inop->inode.iso_mtime,sizeof(struct timeval)); 323*65789Smckusick 324*65789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) { 325*65789Smckusick isofs_tstamp_conv17(ptime,&ana->inop->inode.iso_atime); 326*65789Smckusick ptime += 17; 327*65789Smckusick } else 328*65789Smckusick ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime; 329*65789Smckusick 330*65789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_ATTR) 331*65789Smckusick isofs_tstamp_conv17(ptime,&ana->inop->inode.iso_ctime); 332*65789Smckusick else 333*65789Smckusick ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime; 334*65789Smckusick 335*65789Smckusick } 336*65789Smckusick ana->fields &= ~ISO_SUSP_TSTAMP; 337*65789Smckusick return ISO_SUSP_TSTAMP; 338*65789Smckusick } 339*65789Smckusick 340*65789Smckusick static void 341*65789Smckusick isofs_rrip_deftstamp(isodir,ana) 342*65789Smckusick struct iso_directory_record *isodir; 343*65789Smckusick ISO_RRIP_ANALYZE *ana; 344*65789Smckusick { 345*65789Smckusick isofs_deftstamp(isodir,ana->inop,NULL); 346*65789Smckusick } 347*65789Smckusick 348*65789Smckusick /* 349*65789Smckusick * POSIX device modes 350*65789Smckusick */ 351*65789Smckusick static int 352*65789Smckusick isofs_rrip_device(p,ana) 353*65789Smckusick ISO_RRIP_DEVICE *p; 354*65789Smckusick ISO_RRIP_ANALYZE *ana; 355*65789Smckusick { 356*65789Smckusick unsigned high, low; 357*65789Smckusick 358*65789Smckusick high = isonum_733(p->dev_t_high_l); 359*65789Smckusick low = isonum_733(p->dev_t_low_l); 360*65789Smckusick 361*65789Smckusick if ( high == 0 ) { 362*65789Smckusick ana->inop->inode.iso_rdev = makedev( major(low), minor(low) ); 363*65789Smckusick } else { 364*65789Smckusick ana->inop->inode.iso_rdev = makedev( high, minor(low) ); 365*65789Smckusick } 366*65789Smckusick ana->fields &= ~ISO_SUSP_DEVICE; 367*65789Smckusick return ISO_SUSP_DEVICE; 368*65789Smckusick } 369*65789Smckusick 370*65789Smckusick /* 371*65789Smckusick * Flag indicating 372*65789Smckusick */ 373*65789Smckusick static int 374*65789Smckusick isofs_rrip_idflag(p,ana) 375*65789Smckusick ISO_RRIP_IDFLAG *p; 376*65789Smckusick ISO_RRIP_ANALYZE *ana; 377*65789Smckusick { 378*65789Smckusick ana->fields &= isonum_711(p->flags)|~0xff; /* don't touch high bits */ 379*65789Smckusick /* special handling of RE field */ 380*65789Smckusick if (ana->fields&ISO_SUSP_RELDIR) 381*65789Smckusick return isofs_rrip_reldir(p,ana); 382*65789Smckusick 383*65789Smckusick return ISO_SUSP_IDFLAG; 384*65789Smckusick } 385*65789Smckusick 386*65789Smckusick /* 387*65789Smckusick * Continuation pointer 388*65789Smckusick */ 389*65789Smckusick static int 390*65789Smckusick isofs_rrip_cont(p,ana) 391*65789Smckusick ISO_RRIP_CONT *p; 392*65789Smckusick ISO_RRIP_ANALYZE *ana; 393*65789Smckusick { 394*65789Smckusick ana->iso_ce_blk = isonum_733(p->location); 395*65789Smckusick ana->iso_ce_off = isonum_733(p->offset); 396*65789Smckusick ana->iso_ce_len = isonum_733(p->length); 397*65789Smckusick return ISO_SUSP_CONT; 398*65789Smckusick } 399*65789Smckusick 400*65789Smckusick /* 401*65789Smckusick * System Use end 402*65789Smckusick */ 403*65789Smckusick static int 404*65789Smckusick isofs_rrip_stop(p,ana) 405*65789Smckusick ISO_SUSP_HEADER *p; 406*65789Smckusick ISO_RRIP_ANALYZE *ana; 407*65789Smckusick { 408*65789Smckusick /* stop analyzing */ 409*65789Smckusick ana->fields = 0; 410*65789Smckusick return ISO_SUSP_STOP; 411*65789Smckusick } 412*65789Smckusick 413*65789Smckusick /* 414*65789Smckusick * Extension reference 415*65789Smckusick */ 416*65789Smckusick static int 417*65789Smckusick isofs_rrip_extref(p,ana) 418*65789Smckusick ISO_RRIP_EXTREF *p; 419*65789Smckusick ISO_RRIP_ANALYZE *ana; 420*65789Smckusick { 421*65789Smckusick if (isonum_711(p->len_id) != 10 422*65789Smckusick || bcmp((char *)p + 8,"RRIP_1991A",10) 423*65789Smckusick || isonum_711(p->version) != 1) 424*65789Smckusick return 0; 425*65789Smckusick ana->fields &= ~ISO_SUSP_EXTREF; 426*65789Smckusick return ISO_SUSP_EXTREF; 427*65789Smckusick } 428*65789Smckusick 429*65789Smckusick typedef struct { 430*65789Smckusick char type[2]; 431*65789Smckusick int (*func)(); 432*65789Smckusick void (*func2)(); 433*65789Smckusick int result; 434*65789Smckusick } RRIP_TABLE; 435*65789Smckusick 436*65789Smckusick static int 437*65789Smckusick isofs_rrip_loop(isodir,ana,table) 438*65789Smckusick struct iso_directory_record *isodir; 439*65789Smckusick ISO_RRIP_ANALYZE *ana; 440*65789Smckusick RRIP_TABLE *table; 441*65789Smckusick { 442*65789Smckusick register RRIP_TABLE *ptable; 443*65789Smckusick register ISO_SUSP_HEADER *phead; 444*65789Smckusick register ISO_SUSP_HEADER *pend; 445*65789Smckusick struct buf *bp = NULL; 446*65789Smckusick int i; 447*65789Smckusick char *pwhead; 448*65789Smckusick int result; 449*65789Smckusick 450*65789Smckusick /* 451*65789Smckusick * Note: If name length is odd, 452*65789Smckusick * it will be padding 1 byte after the name 453*65789Smckusick */ 454*65789Smckusick pwhead = isodir->name + isonum_711(isodir->name_len); 455*65789Smckusick if (!(isonum_711(isodir->name_len)&1)) 456*65789Smckusick pwhead++; 457*65789Smckusick 458*65789Smckusick /* If it's not the '.' entry of the root dir obey SP field */ 459*65789Smckusick if (*isodir->name != 0 460*65789Smckusick || isonum_733(isodir->extent) != ana->imp->root_extent) 461*65789Smckusick pwhead += ana->imp->rr_skip; 462*65789Smckusick else 463*65789Smckusick pwhead += ana->imp->rr_skip0; 464*65789Smckusick 465*65789Smckusick phead = (ISO_SUSP_HEADER *)pwhead; 466*65789Smckusick pend = (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length)); 467*65789Smckusick 468*65789Smckusick result = 0; 469*65789Smckusick while (1) { 470*65789Smckusick ana->iso_ce_len = 0; 471*65789Smckusick /* 472*65789Smckusick * Note: "pend" should be more than one SUSP header 473*65789Smckusick */ 474*65789Smckusick while (pend >= phead + 1) { 475*65789Smckusick if (isonum_711(phead->version) == 1) { 476*65789Smckusick for (ptable = table; ptable->func; ptable++) { 477*65789Smckusick if (*phead->type == *ptable->type 478*65789Smckusick && phead->type[1] == ptable->type[1]) { 479*65789Smckusick result |= ptable->func(phead,ana); 480*65789Smckusick break; 481*65789Smckusick } 482*65789Smckusick } 483*65789Smckusick if (!ana->fields) 484*65789Smckusick break; 485*65789Smckusick } 486*65789Smckusick /* 487*65789Smckusick * move to next SUSP 488*65789Smckusick * Hopefully this works with newer versions, too 489*65789Smckusick */ 490*65789Smckusick phead = (ISO_SUSP_HEADER *)((char *)phead + isonum_711(phead->length)); 491*65789Smckusick } 492*65789Smckusick 493*65789Smckusick if ( ana->fields && ana->iso_ce_len ) { 494*65789Smckusick if (ana->iso_ce_blk >= ana->imp->volume_space_size 495*65789Smckusick || ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size 496*65789Smckusick || bread(ana->imp->im_devvp, 497*65789Smckusick ana->iso_ce_blk * ana->imp->logical_block_size / DEV_BSIZE, 498*65789Smckusick ana->imp->logical_block_size,NOCRED,&bp)) 499*65789Smckusick /* what to do now? */ 500*65789Smckusick break; 501*65789Smckusick phead = (ISO_SUSP_HEADER *)(bp->b_un.b_addr + ana->iso_ce_off); 502*65789Smckusick pend = (ISO_SUSP_HEADER *) ((char *)phead + ana->iso_ce_len); 503*65789Smckusick } else 504*65789Smckusick break; 505*65789Smckusick } 506*65789Smckusick if (bp) 507*65789Smckusick brelse(bp); 508*65789Smckusick /* 509*65789Smckusick * If we don't find the Basic SUSP stuffs, just set default value 510*65789Smckusick * ( attribute/time stamp ) 511*65789Smckusick */ 512*65789Smckusick for (ptable = table; ptable->func2; ptable++) 513*65789Smckusick if (!(ptable->result&result)) 514*65789Smckusick ptable->func2(isodir,ana); 515*65789Smckusick 516*65789Smckusick return result; 517*65789Smckusick } 518*65789Smckusick 519*65789Smckusick static RRIP_TABLE rrip_table_analyze[] = { 520*65789Smckusick { "PX", isofs_rrip_attr, isofs_rrip_defattr, ISO_SUSP_ATTR }, 521*65789Smckusick { "TF", isofs_rrip_tstamp, isofs_rrip_deftstamp, ISO_SUSP_TSTAMP }, 522*65789Smckusick { "PN", isofs_rrip_device, 0, ISO_SUSP_DEVICE }, 523*65789Smckusick { "RR", isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG }, 524*65789Smckusick { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT }, 525*65789Smckusick { "ST", isofs_rrip_stop, 0, ISO_SUSP_STOP }, 526*65789Smckusick { "", 0, 0, 0 } 527*65789Smckusick }; 528*65789Smckusick 529*65789Smckusick int 530*65789Smckusick isofs_rrip_analyze(isodir,inop,imp) 531*65789Smckusick struct iso_directory_record *isodir; 532*65789Smckusick struct iso_node *inop; 533*65789Smckusick struct iso_mnt *imp; 534*65789Smckusick { 535*65789Smckusick ISO_RRIP_ANALYZE analyze; 536*65789Smckusick 537*65789Smckusick analyze.inop = inop; 538*65789Smckusick analyze.imp = imp; 539*65789Smckusick analyze.fields = ISO_SUSP_ATTR|ISO_SUSP_TSTAMP|ISO_SUSP_DEVICE; 540*65789Smckusick 541*65789Smckusick return isofs_rrip_loop(isodir,&analyze,rrip_table_analyze); 542*65789Smckusick } 543*65789Smckusick 544*65789Smckusick /* 545*65789Smckusick * Get Alternate Name from 'AL' record 546*65789Smckusick * If either no AL record or 0 length, 547*65789Smckusick * it will be return the translated ISO9660 name, 548*65789Smckusick */ 549*65789Smckusick static RRIP_TABLE rrip_table_getname[] = { 550*65789Smckusick { "NM", isofs_rrip_altname, isofs_rrip_defname, ISO_SUSP_ALTNAME }, 551*65789Smckusick { "CL", isofs_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK }, 552*65789Smckusick { "PL", isofs_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK }, 553*65789Smckusick { "RE", isofs_rrip_reldir, 0, ISO_SUSP_RELDIR }, 554*65789Smckusick { "RR", isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG }, 555*65789Smckusick { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT }, 556*65789Smckusick { "ST", isofs_rrip_stop, 0, ISO_SUSP_STOP }, 557*65789Smckusick { "", 0, 0, 0 } 558*65789Smckusick }; 559*65789Smckusick 560*65789Smckusick int 561*65789Smckusick isofs_rrip_getname(isodir,outbuf,outlen,inump,imp) 562*65789Smckusick struct iso_directory_record *isodir; 563*65789Smckusick char *outbuf; 564*65789Smckusick u_short *outlen; 565*65789Smckusick ino_t *inump; 566*65789Smckusick struct iso_mnt *imp; 567*65789Smckusick { 568*65789Smckusick ISO_RRIP_ANALYZE analyze; 569*65789Smckusick RRIP_TABLE *tab; 570*65789Smckusick 571*65789Smckusick analyze.outbuf = outbuf; 572*65789Smckusick analyze.outlen = outlen; 573*65789Smckusick analyze.maxlen = NAME_MAX; 574*65789Smckusick analyze.inump = inump; 575*65789Smckusick analyze.imp = imp; 576*65789Smckusick analyze.fields = ISO_SUSP_ALTNAME|ISO_SUSP_RELDIR|ISO_SUSP_CLINK|ISO_SUSP_PLINK; 577*65789Smckusick *outlen = 0; 578*65789Smckusick 579*65789Smckusick tab = rrip_table_getname; 580*65789Smckusick if (*isodir->name == 0 581*65789Smckusick || *isodir->name == 1) { 582*65789Smckusick isofs_rrip_defname(isodir,&analyze); 583*65789Smckusick 584*65789Smckusick analyze.fields &= ~ISO_SUSP_ALTNAME; 585*65789Smckusick tab++; 586*65789Smckusick } 587*65789Smckusick 588*65789Smckusick return isofs_rrip_loop(isodir,&analyze,tab); 589*65789Smckusick } 590*65789Smckusick 591*65789Smckusick /* 592*65789Smckusick * Get Symbolic Name from 'SL' record 593*65789Smckusick * 594*65789Smckusick * Note: isodir should contains SL record! 595*65789Smckusick */ 596*65789Smckusick static RRIP_TABLE rrip_table_getsymname[] = { 597*65789Smckusick { "SL", isofs_rrip_slink, 0, ISO_SUSP_SLINK }, 598*65789Smckusick { "RR", isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG }, 599*65789Smckusick { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT }, 600*65789Smckusick { "ST", isofs_rrip_stop, 0, ISO_SUSP_STOP }, 601*65789Smckusick { "", 0, 0, 0 } 602*65789Smckusick }; 603*65789Smckusick 604*65789Smckusick int 605*65789Smckusick isofs_rrip_getsymname(isodir,outbuf,outlen,imp) 606*65789Smckusick struct iso_directory_record *isodir; 607*65789Smckusick char *outbuf; 608*65789Smckusick u_short *outlen; 609*65789Smckusick struct iso_mnt *imp; 610*65789Smckusick { 611*65789Smckusick ISO_RRIP_ANALYZE analyze; 612*65789Smckusick 613*65789Smckusick analyze.outbuf = outbuf; 614*65789Smckusick analyze.outlen = outlen; 615*65789Smckusick *outlen = 0; 616*65789Smckusick analyze.maxlen = MAXPATHLEN; 617*65789Smckusick analyze.cont = 1; /* don't start with a slash */ 618*65789Smckusick analyze.imp = imp; 619*65789Smckusick analyze.fields = ISO_SUSP_SLINK; 620*65789Smckusick 621*65789Smckusick return (isofs_rrip_loop(isodir,&analyze,rrip_table_getsymname)&ISO_SUSP_SLINK); 622*65789Smckusick } 623*65789Smckusick 624*65789Smckusick static RRIP_TABLE rrip_table_extref[] = { 625*65789Smckusick { "ER", isofs_rrip_extref, 0, ISO_SUSP_EXTREF }, 626*65789Smckusick { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT }, 627*65789Smckusick { "ST", isofs_rrip_stop, 0, ISO_SUSP_STOP }, 628*65789Smckusick { "", 0, 0, 0 } 629*65789Smckusick }; 630*65789Smckusick 631*65789Smckusick /* 632*65789Smckusick * Check for Rock Ridge Extension and return offset of its fields. 633*65789Smckusick * Note: We require the ER field. 634*65789Smckusick */ 635*65789Smckusick int 636*65789Smckusick isofs_rrip_offset(isodir,imp) 637*65789Smckusick struct iso_directory_record *isodir; 638*65789Smckusick struct iso_mnt *imp; 639*65789Smckusick { 640*65789Smckusick ISO_RRIP_OFFSET *p; 641*65789Smckusick ISO_RRIP_ANALYZE analyze; 642*65789Smckusick 643*65789Smckusick imp->rr_skip0 = 0; 644*65789Smckusick p = (ISO_RRIP_OFFSET *)(isodir->name + 1); 645*65789Smckusick if (bcmp(p,"SP\7\1\276\357",6)) { 646*65789Smckusick /* Maybe, it's a CDROM XA disc? */ 647*65789Smckusick imp->rr_skip0 = 15; 648*65789Smckusick p = (ISO_RRIP_OFFSET *)((char *)p + 15); 649*65789Smckusick if (bcmp(p,"SP\7\1\276\357",6)) 650*65789Smckusick return -1; 651*65789Smckusick } 652*65789Smckusick 653*65789Smckusick analyze.imp = imp; 654*65789Smckusick analyze.fields = ISO_SUSP_EXTREF; 655*65789Smckusick if (!(isofs_rrip_loop(isodir,&analyze,rrip_table_extref)&ISO_SUSP_EXTREF)) 656*65789Smckusick return -1; 657*65789Smckusick 658*65789Smckusick return isonum_711(p->skip); 659*65789Smckusick } 660