165789Smckusick /*- 265789Smckusick * Copyright (c) 1993, 1994 365789Smckusick * The Regents of the University of California. All rights reserved. 465789Smckusick * 565789Smckusick * This code is derived from software contributed to Berkeley 665789Smckusick * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension 765789Smckusick * Support code is derived from software contributed to Berkeley 865789Smckusick * by Atsushi Murai (amurai@spec.co.jp). 965789Smckusick * 1065789Smckusick * %sccs.include.redist.c% 1165789Smckusick * 12*67699Smckusick * @(#)cd9660_rrip.c 8.5 (Berkeley) 08/17/94 1365789Smckusick */ 1465789Smckusick 1565789Smckusick #include <sys/param.h> 1665789Smckusick #include <sys/namei.h> 1765789Smckusick #include <sys/buf.h> 1865789Smckusick #include <sys/file.h> 1965789Smckusick #include <sys/vnode.h> 2065789Smckusick #include <sys/mount.h> 2165789Smckusick #include <sys/kernel.h> 2265789Smckusick #include <sys/stat.h> 2365789Smckusick #include <sys/types.h> 2465789Smckusick 2565789Smckusick #include <sys/time.h> 2665789Smckusick 2765789Smckusick #include <isofs/cd9660/iso.h> 2865855Smckusick #include <isofs/cd9660/cd9660_node.h> 2965855Smckusick #include <isofs/cd9660/cd9660_rrip.h> 3065789Smckusick #include <isofs/cd9660/iso_rrip.h> 3165789Smckusick 3265789Smckusick /* 3365789Smckusick * POSIX file attribute 3465789Smckusick */ 3565789Smckusick static int 3665855Smckusick cd9660_rrip_attr(p,ana) 3765789Smckusick ISO_RRIP_ATTR *p; 3865789Smckusick ISO_RRIP_ANALYZE *ana; 3965789Smckusick { 4065789Smckusick ana->inop->inode.iso_mode = isonum_731(p->mode_l); 4165789Smckusick ana->inop->inode.iso_uid = (uid_t)isonum_731(p->uid_l); 4265789Smckusick ana->inop->inode.iso_gid = (gid_t)isonum_731(p->gid_l); 4365789Smckusick ana->inop->inode.iso_links = isonum_731(p->links_l); 4465789Smckusick ana->fields &= ~ISO_SUSP_ATTR; 4565789Smckusick return ISO_SUSP_ATTR; 4665789Smckusick } 4765789Smckusick 4865789Smckusick static void 4965855Smckusick cd9660_rrip_defattr(isodir,ana) 5065789Smckusick struct iso_directory_record *isodir; 5165789Smckusick ISO_RRIP_ANALYZE *ana; 5265789Smckusick { 5365789Smckusick /* But this is a required field! */ 5465789Smckusick printf("RRIP without PX field?\n"); 5565855Smckusick cd9660_defattr(isodir,ana->inop,NULL); 5665789Smckusick } 5765789Smckusick 5865789Smckusick /* 5965789Smckusick * Symbolic Links 6065789Smckusick */ 6165789Smckusick static int 6265855Smckusick cd9660_rrip_slink(p,ana) 6365789Smckusick ISO_RRIP_SLINK *p; 6465789Smckusick ISO_RRIP_ANALYZE *ana; 6565789Smckusick { 6665789Smckusick register ISO_RRIP_SLINK_COMPONENT *pcomp; 6765789Smckusick register ISO_RRIP_SLINK_COMPONENT *pcompe; 6865789Smckusick int len, wlen, cont; 6965789Smckusick char *outbuf, *inbuf; 7065789Smckusick 7165789Smckusick pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component; 7265789Smckusick pcompe = (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length)); 7365789Smckusick len = *ana->outlen; 7465789Smckusick outbuf = ana->outbuf; 7565789Smckusick cont = ana->cont; 7665789Smckusick 7765789Smckusick /* 7865789Smckusick * Gathering a Symbolic name from each component with path 7965789Smckusick */ 8065789Smckusick for (; 8165789Smckusick pcomp < pcompe; 8265789Smckusick pcomp = (ISO_RRIP_SLINK_COMPONENT *)((char *)pcomp + ISO_RRIP_SLSIZ 8365789Smckusick + isonum_711(pcomp->clen))) { 8465789Smckusick 8565789Smckusick if (!cont) { 8665789Smckusick if (len < ana->maxlen) { 8765789Smckusick len++; 8865789Smckusick *outbuf++ = '/'; 8965789Smckusick } 9065789Smckusick } 9165789Smckusick cont = 0; 9265789Smckusick 9365789Smckusick inbuf = ".."; 9465789Smckusick wlen = 0; 9565789Smckusick 9665789Smckusick switch (*pcomp->cflag) { 9765789Smckusick 9865789Smckusick case ISO_SUSP_CFLAG_CURRENT: 9965789Smckusick /* Inserting Current */ 10065789Smckusick wlen = 1; 10165789Smckusick break; 10265789Smckusick 10365789Smckusick case ISO_SUSP_CFLAG_PARENT: 10465789Smckusick /* Inserting Parent */ 10565789Smckusick wlen = 2; 10665789Smckusick break; 10765789Smckusick 10865789Smckusick case ISO_SUSP_CFLAG_ROOT: 10965789Smckusick /* Inserting slash for ROOT */ 11065789Smckusick /* start over from beginning(?) */ 11165789Smckusick outbuf -= len; 11265789Smckusick len = 0; 11365789Smckusick break; 11465789Smckusick 11565789Smckusick case ISO_SUSP_CFLAG_VOLROOT: 11665789Smckusick /* Inserting a mount point i.e. "/cdrom" */ 11765789Smckusick /* same as above */ 11865789Smckusick outbuf -= len; 11965789Smckusick len = 0; 12065789Smckusick inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname; 12165789Smckusick wlen = strlen(inbuf); 12265789Smckusick break; 12365789Smckusick 12465789Smckusick case ISO_SUSP_CFLAG_HOST: 12565789Smckusick /* Inserting hostname i.e. "kurt.tools.de" */ 12665789Smckusick inbuf = hostname; 12765789Smckusick wlen = hostnamelen; 12865789Smckusick break; 12965789Smckusick 13065789Smckusick case ISO_SUSP_CFLAG_CONTINUE: 13165789Smckusick cont = 1; 13265789Smckusick /* fall thru */ 13365789Smckusick case 0: 13465789Smckusick /* Inserting component */ 13565789Smckusick wlen = isonum_711(pcomp->clen); 13665789Smckusick inbuf = pcomp->name; 13765789Smckusick break; 13865789Smckusick default: 13965789Smckusick printf("RRIP with incorrect flags?"); 14065789Smckusick wlen = ana->maxlen + 1; 14165789Smckusick break; 14265789Smckusick } 14365789Smckusick 14465789Smckusick if (len + wlen > ana->maxlen) { 14565789Smckusick /* indicate error to caller */ 14665789Smckusick ana->cont = 1; 14765789Smckusick ana->fields = 0; 14865789Smckusick ana->outbuf -= *ana->outlen; 14965789Smckusick *ana->outlen = 0; 15065789Smckusick return 0; 15165789Smckusick } 15265789Smckusick 15365789Smckusick bcopy(inbuf,outbuf,wlen); 15465789Smckusick outbuf += wlen; 15565789Smckusick len += wlen; 15665789Smckusick 15765789Smckusick } 15865789Smckusick ana->outbuf = outbuf; 15965789Smckusick *ana->outlen = len; 16065789Smckusick ana->cont = cont; 16165789Smckusick 16265789Smckusick if (!isonum_711(p->flags)) { 16365789Smckusick ana->fields &= ~ISO_SUSP_SLINK; 16465789Smckusick return ISO_SUSP_SLINK; 16565789Smckusick } 16665789Smckusick return 0; 16765789Smckusick } 16865789Smckusick 16965789Smckusick /* 17065789Smckusick * Alternate name 17165789Smckusick */ 17265789Smckusick static int 17365855Smckusick cd9660_rrip_altname(p,ana) 17465789Smckusick ISO_RRIP_ALTNAME *p; 17565789Smckusick ISO_RRIP_ANALYZE *ana; 17665789Smckusick { 17765789Smckusick char *inbuf; 17865789Smckusick int wlen; 17965789Smckusick int cont; 18065789Smckusick 18165789Smckusick inbuf = ".."; 18265789Smckusick wlen = 0; 18365789Smckusick cont = 0; 18465789Smckusick 18565789Smckusick switch (*p->flags) { 18665789Smckusick case ISO_SUSP_CFLAG_CURRENT: 18765789Smckusick /* Inserting Current */ 18865789Smckusick wlen = 1; 18965789Smckusick break; 19065789Smckusick 19165789Smckusick case ISO_SUSP_CFLAG_PARENT: 19265789Smckusick /* Inserting Parent */ 19365789Smckusick wlen = 2; 19465789Smckusick break; 19565789Smckusick 19665789Smckusick case ISO_SUSP_CFLAG_HOST: 19765789Smckusick /* Inserting hostname i.e. "kurt.tools.de" */ 19865789Smckusick inbuf = hostname; 19965789Smckusick wlen = hostnamelen; 20065789Smckusick break; 20165789Smckusick 20265789Smckusick case ISO_SUSP_CFLAG_CONTINUE: 20365789Smckusick cont = 1; 20465789Smckusick /* fall thru */ 20565789Smckusick case 0: 20665789Smckusick /* Inserting component */ 20765789Smckusick wlen = isonum_711(p->h.length) - 5; 20865789Smckusick inbuf = (char *)p + 5; 20965789Smckusick break; 21065789Smckusick 21165789Smckusick default: 21265789Smckusick printf("RRIP with incorrect NM flags?\n"); 21365789Smckusick wlen = ana->maxlen + 1; 21465789Smckusick break; 21565789Smckusick } 21665789Smckusick 21765789Smckusick if ((*ana->outlen += wlen) > ana->maxlen) { 21865789Smckusick /* treat as no name field */ 21965789Smckusick ana->fields &= ~ISO_SUSP_ALTNAME; 22065789Smckusick ana->outbuf -= *ana->outlen - wlen; 22165789Smckusick *ana->outlen = 0; 22265789Smckusick return 0; 22365789Smckusick } 22465789Smckusick 22565789Smckusick bcopy(inbuf,ana->outbuf,wlen); 22665789Smckusick ana->outbuf += wlen; 22765789Smckusick 22865789Smckusick if (!cont) { 22965789Smckusick ana->fields &= ~ISO_SUSP_ALTNAME; 23065789Smckusick return ISO_SUSP_ALTNAME; 23165789Smckusick } 23265789Smckusick return 0; 23365789Smckusick } 23465789Smckusick 23565789Smckusick static void 23665855Smckusick cd9660_rrip_defname(isodir,ana) 23765789Smckusick struct iso_directory_record *isodir; 23865789Smckusick ISO_RRIP_ANALYZE *ana; 23965789Smckusick { 24065789Smckusick strcpy(ana->outbuf,".."); 24165789Smckusick switch (*isodir->name) { 24265789Smckusick default: 24365789Smckusick isofntrans(isodir->name,isonum_711(isodir->name_len), 24465789Smckusick ana->outbuf,ana->outlen, 24565789Smckusick 1,isonum_711(isodir->flags)&4); 24665789Smckusick break; 24765789Smckusick case 0: 24865789Smckusick *ana->outlen = 1; 24965789Smckusick break; 25065789Smckusick case 1: 25165789Smckusick *ana->outlen = 2; 25265789Smckusick break; 25365789Smckusick } 25465789Smckusick } 25565789Smckusick 25665789Smckusick /* 25765789Smckusick * Parent or Child Link 25865789Smckusick */ 25965789Smckusick static int 26065855Smckusick cd9660_rrip_pclink(p,ana) 26165789Smckusick ISO_RRIP_CLINK *p; 26265789Smckusick ISO_RRIP_ANALYZE *ana; 26365789Smckusick { 26465789Smckusick *ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift; 26565789Smckusick ana->fields &= ~(ISO_SUSP_CLINK|ISO_SUSP_PLINK); 26665789Smckusick return *p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK; 26765789Smckusick } 26865789Smckusick 26965789Smckusick /* 27065789Smckusick * Relocated directory 27165789Smckusick */ 27265789Smckusick static int 27365855Smckusick cd9660_rrip_reldir(p,ana) 27465789Smckusick ISO_RRIP_RELDIR *p; 27565789Smckusick ISO_RRIP_ANALYZE *ana; 27665789Smckusick { 27765789Smckusick /* special hack to make caller aware of RE field */ 27865789Smckusick *ana->outlen = 0; 27965789Smckusick ana->fields = 0; 28065789Smckusick return ISO_SUSP_RELDIR|ISO_SUSP_ALTNAME|ISO_SUSP_CLINK|ISO_SUSP_PLINK; 28165789Smckusick } 28265789Smckusick 28365789Smckusick static int 28465855Smckusick cd9660_rrip_tstamp(p,ana) 28565789Smckusick ISO_RRIP_TSTAMP *p; 28665789Smckusick ISO_RRIP_ANALYZE *ana; 28765789Smckusick { 28865789Smckusick unsigned char *ptime; 28965789Smckusick 29065789Smckusick ptime = p->time; 29165789Smckusick 29265789Smckusick /* Check a format of time stamp (7bytes/17bytes) */ 29365789Smckusick if (!(*p->flags&ISO_SUSP_TSTAMP_FORM17)) { 29465789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_CREAT) 29565789Smckusick ptime += 7; 29665789Smckusick 29765789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) { 29865855Smckusick cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_mtime); 29965789Smckusick ptime += 7; 30065789Smckusick } else 30165789Smckusick bzero(&ana->inop->inode.iso_mtime,sizeof(struct timeval)); 30265789Smckusick 30365789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) { 30465855Smckusick cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_atime); 30565789Smckusick ptime += 7; 30665789Smckusick } else 30765789Smckusick ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime; 30865789Smckusick 30965789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_ATTR) 31065855Smckusick cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_ctime); 31165789Smckusick else 31265789Smckusick ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime; 31365789Smckusick 31465789Smckusick } else { 31565789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_CREAT) 31665789Smckusick ptime += 17; 31765789Smckusick 31865789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) { 31965855Smckusick cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_mtime); 32065789Smckusick ptime += 17; 32165789Smckusick } else 32265789Smckusick bzero(&ana->inop->inode.iso_mtime,sizeof(struct timeval)); 32365789Smckusick 32465789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) { 32565855Smckusick cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_atime); 32665789Smckusick ptime += 17; 32765789Smckusick } else 32865789Smckusick ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime; 32965789Smckusick 33065789Smckusick if (*p->flags&ISO_SUSP_TSTAMP_ATTR) 33165855Smckusick cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_ctime); 33265789Smckusick else 33365789Smckusick ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime; 33465789Smckusick 33565789Smckusick } 33665789Smckusick ana->fields &= ~ISO_SUSP_TSTAMP; 33765789Smckusick return ISO_SUSP_TSTAMP; 33865789Smckusick } 33965789Smckusick 34065789Smckusick static void 34165855Smckusick cd9660_rrip_deftstamp(isodir,ana) 34265789Smckusick struct iso_directory_record *isodir; 34365789Smckusick ISO_RRIP_ANALYZE *ana; 34465789Smckusick { 34565855Smckusick cd9660_deftstamp(isodir,ana->inop,NULL); 34665789Smckusick } 34765789Smckusick 34865789Smckusick /* 34965789Smckusick * POSIX device modes 35065789Smckusick */ 35165789Smckusick static int 35265855Smckusick cd9660_rrip_device(p,ana) 35365789Smckusick ISO_RRIP_DEVICE *p; 35465789Smckusick ISO_RRIP_ANALYZE *ana; 35565789Smckusick { 35665789Smckusick unsigned high, low; 35765789Smckusick 35865789Smckusick high = isonum_733(p->dev_t_high_l); 35965789Smckusick low = isonum_733(p->dev_t_low_l); 36065789Smckusick 36167377Smkm if (high == 0) 36267377Smkm ana->inop->inode.iso_rdev = makedev(major(low), minor(low)); 36367377Smkm else 36467377Smkm ana->inop->inode.iso_rdev = makedev(high, minor(low)); 36565789Smckusick ana->fields &= ~ISO_SUSP_DEVICE; 36665789Smckusick return ISO_SUSP_DEVICE; 36765789Smckusick } 36865789Smckusick 36965789Smckusick /* 37065789Smckusick * Flag indicating 37165789Smckusick */ 37265789Smckusick static int 37365855Smckusick cd9660_rrip_idflag(p,ana) 37465789Smckusick ISO_RRIP_IDFLAG *p; 37565789Smckusick ISO_RRIP_ANALYZE *ana; 37665789Smckusick { 37765789Smckusick ana->fields &= isonum_711(p->flags)|~0xff; /* don't touch high bits */ 37865789Smckusick /* special handling of RE field */ 37965789Smckusick if (ana->fields&ISO_SUSP_RELDIR) 38065855Smckusick return cd9660_rrip_reldir(p,ana); 38165789Smckusick 38265789Smckusick return ISO_SUSP_IDFLAG; 38365789Smckusick } 38465789Smckusick 38565789Smckusick /* 38665789Smckusick * Continuation pointer 38765789Smckusick */ 38865789Smckusick static int 38965855Smckusick cd9660_rrip_cont(p,ana) 39065789Smckusick ISO_RRIP_CONT *p; 39165789Smckusick ISO_RRIP_ANALYZE *ana; 39265789Smckusick { 39365789Smckusick ana->iso_ce_blk = isonum_733(p->location); 39465789Smckusick ana->iso_ce_off = isonum_733(p->offset); 39565789Smckusick ana->iso_ce_len = isonum_733(p->length); 39665789Smckusick return ISO_SUSP_CONT; 39765789Smckusick } 39865789Smckusick 39965789Smckusick /* 40065789Smckusick * System Use end 40165789Smckusick */ 40265789Smckusick static int 40365855Smckusick cd9660_rrip_stop(p,ana) 40465789Smckusick ISO_SUSP_HEADER *p; 40565789Smckusick ISO_RRIP_ANALYZE *ana; 40665789Smckusick { 40765789Smckusick return ISO_SUSP_STOP; 40865789Smckusick } 40965789Smckusick 41065789Smckusick /* 41165789Smckusick * Extension reference 41265789Smckusick */ 41365789Smckusick static int 41465855Smckusick cd9660_rrip_extref(p,ana) 41565789Smckusick ISO_RRIP_EXTREF *p; 41665789Smckusick ISO_RRIP_ANALYZE *ana; 41765789Smckusick { 41865789Smckusick if (isonum_711(p->len_id) != 10 41965789Smckusick || bcmp((char *)p + 8,"RRIP_1991A",10) 42065789Smckusick || isonum_711(p->version) != 1) 42165789Smckusick return 0; 42265789Smckusick ana->fields &= ~ISO_SUSP_EXTREF; 42365789Smckusick return ISO_SUSP_EXTREF; 42465789Smckusick } 42565789Smckusick 42665789Smckusick typedef struct { 42765789Smckusick char type[2]; 42865789Smckusick int (*func)(); 42965789Smckusick void (*func2)(); 43065789Smckusick int result; 43165789Smckusick } RRIP_TABLE; 43265789Smckusick 43365789Smckusick static int 43465855Smckusick cd9660_rrip_loop(isodir,ana,table) 43565789Smckusick struct iso_directory_record *isodir; 43665789Smckusick ISO_RRIP_ANALYZE *ana; 43765789Smckusick RRIP_TABLE *table; 43865789Smckusick { 43965789Smckusick register RRIP_TABLE *ptable; 44065789Smckusick register ISO_SUSP_HEADER *phead; 44165789Smckusick register ISO_SUSP_HEADER *pend; 44265789Smckusick struct buf *bp = NULL; 44365789Smckusick int i; 44465789Smckusick char *pwhead; 44565789Smckusick int result; 44665789Smckusick 44765789Smckusick /* 44865789Smckusick * Note: If name length is odd, 44965789Smckusick * it will be padding 1 byte after the name 45065789Smckusick */ 45165789Smckusick pwhead = isodir->name + isonum_711(isodir->name_len); 45265789Smckusick if (!(isonum_711(isodir->name_len)&1)) 45365789Smckusick pwhead++; 45465789Smckusick 45565789Smckusick /* If it's not the '.' entry of the root dir obey SP field */ 45665789Smckusick if (*isodir->name != 0 45765789Smckusick || isonum_733(isodir->extent) != ana->imp->root_extent) 45865789Smckusick pwhead += ana->imp->rr_skip; 45965789Smckusick else 46065789Smckusick pwhead += ana->imp->rr_skip0; 46165789Smckusick 46265789Smckusick phead = (ISO_SUSP_HEADER *)pwhead; 46365789Smckusick pend = (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length)); 46465789Smckusick 46565789Smckusick result = 0; 46665789Smckusick while (1) { 46765789Smckusick ana->iso_ce_len = 0; 46865789Smckusick /* 46965789Smckusick * Note: "pend" should be more than one SUSP header 47065789Smckusick */ 47165789Smckusick while (pend >= phead + 1) { 47265789Smckusick if (isonum_711(phead->version) == 1) { 47365789Smckusick for (ptable = table; ptable->func; ptable++) { 47465789Smckusick if (*phead->type == *ptable->type 47565789Smckusick && phead->type[1] == ptable->type[1]) { 47665789Smckusick result |= ptable->func(phead,ana); 47765789Smckusick break; 47865789Smckusick } 47965789Smckusick } 48065789Smckusick if (!ana->fields) 48165789Smckusick break; 48265789Smckusick } 48367377Smkm if (result&ISO_SUSP_STOP) { 48467377Smkm result &= ~ISO_SUSP_STOP; 48567377Smkm break; 48667377Smkm } 48767377Smkm /* plausibility check */ 48867377Smkm if (isonum_711(phead->length) < sizeof(*phead)) 48967377Smkm break; 49065789Smckusick /* 49165789Smckusick * move to next SUSP 49265789Smckusick * Hopefully this works with newer versions, too 49365789Smckusick */ 49465789Smckusick phead = (ISO_SUSP_HEADER *)((char *)phead + isonum_711(phead->length)); 49565789Smckusick } 49665789Smckusick 49767377Smkm if (ana->fields && ana->iso_ce_len) { 49865789Smckusick if (ana->iso_ce_blk >= ana->imp->volume_space_size 49965789Smckusick || ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size 50065789Smckusick || bread(ana->imp->im_devvp, 50165789Smckusick ana->iso_ce_blk * ana->imp->logical_block_size / DEV_BSIZE, 50265789Smckusick ana->imp->logical_block_size,NOCRED,&bp)) 50365789Smckusick /* what to do now? */ 50465789Smckusick break; 50565789Smckusick phead = (ISO_SUSP_HEADER *)(bp->b_un.b_addr + ana->iso_ce_off); 50665789Smckusick pend = (ISO_SUSP_HEADER *) ((char *)phead + ana->iso_ce_len); 50765789Smckusick } else 50865789Smckusick break; 50965789Smckusick } 51065789Smckusick if (bp) 51165789Smckusick brelse(bp); 51265789Smckusick /* 51365789Smckusick * If we don't find the Basic SUSP stuffs, just set default value 51467377Smkm * (attribute/time stamp) 51565789Smckusick */ 51665789Smckusick for (ptable = table; ptable->func2; ptable++) 51765789Smckusick if (!(ptable->result&result)) 51865789Smckusick ptable->func2(isodir,ana); 51965789Smckusick 52065789Smckusick return result; 52165789Smckusick } 52265789Smckusick 52367377Smkm /* 52467377Smkm * Get Attributes. 52567377Smkm */ 52665789Smckusick static RRIP_TABLE rrip_table_analyze[] = { 52765855Smckusick { "PX", cd9660_rrip_attr, cd9660_rrip_defattr, ISO_SUSP_ATTR }, 52865855Smckusick { "TF", cd9660_rrip_tstamp, cd9660_rrip_deftstamp, ISO_SUSP_TSTAMP }, 52965855Smckusick { "PN", cd9660_rrip_device, 0, ISO_SUSP_DEVICE }, 53065855Smckusick { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG }, 53165855Smckusick { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT }, 53265855Smckusick { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP }, 53365789Smckusick { "", 0, 0, 0 } 53465789Smckusick }; 53565789Smckusick 53665789Smckusick int 53765855Smckusick cd9660_rrip_analyze(isodir,inop,imp) 53865789Smckusick struct iso_directory_record *isodir; 53965789Smckusick struct iso_node *inop; 54065789Smckusick struct iso_mnt *imp; 54165789Smckusick { 54265789Smckusick ISO_RRIP_ANALYZE analyze; 54365789Smckusick 54465789Smckusick analyze.inop = inop; 54565789Smckusick analyze.imp = imp; 54665789Smckusick analyze.fields = ISO_SUSP_ATTR|ISO_SUSP_TSTAMP|ISO_SUSP_DEVICE; 54765789Smckusick 54865855Smckusick return cd9660_rrip_loop(isodir,&analyze,rrip_table_analyze); 54965789Smckusick } 55065789Smckusick 55165789Smckusick /* 55267377Smkm * Get Alternate Name. 55365789Smckusick */ 55465789Smckusick static RRIP_TABLE rrip_table_getname[] = { 55565855Smckusick { "NM", cd9660_rrip_altname, cd9660_rrip_defname, ISO_SUSP_ALTNAME }, 55665855Smckusick { "CL", cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK }, 55765855Smckusick { "PL", cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK }, 55865855Smckusick { "RE", cd9660_rrip_reldir, 0, ISO_SUSP_RELDIR }, 55965855Smckusick { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG }, 56065855Smckusick { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT }, 56165855Smckusick { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP }, 56265789Smckusick { "", 0, 0, 0 } 56365789Smckusick }; 56465789Smckusick 56565789Smckusick int 56665855Smckusick cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp) 56765789Smckusick struct iso_directory_record *isodir; 56865789Smckusick char *outbuf; 56965789Smckusick u_short *outlen; 57065789Smckusick ino_t *inump; 57165789Smckusick struct iso_mnt *imp; 57265789Smckusick { 57365789Smckusick ISO_RRIP_ANALYZE analyze; 57465789Smckusick RRIP_TABLE *tab; 57565789Smckusick 57665789Smckusick analyze.outbuf = outbuf; 57765789Smckusick analyze.outlen = outlen; 57865789Smckusick analyze.maxlen = NAME_MAX; 57965789Smckusick analyze.inump = inump; 58065789Smckusick analyze.imp = imp; 58165789Smckusick analyze.fields = ISO_SUSP_ALTNAME|ISO_SUSP_RELDIR|ISO_SUSP_CLINK|ISO_SUSP_PLINK; 58265789Smckusick *outlen = 0; 58365789Smckusick 58465789Smckusick tab = rrip_table_getname; 58565789Smckusick if (*isodir->name == 0 58665789Smckusick || *isodir->name == 1) { 58765855Smckusick cd9660_rrip_defname(isodir,&analyze); 58865789Smckusick 58965789Smckusick analyze.fields &= ~ISO_SUSP_ALTNAME; 59065789Smckusick tab++; 59165789Smckusick } 59265789Smckusick 59365855Smckusick return cd9660_rrip_loop(isodir,&analyze,tab); 59465789Smckusick } 59565789Smckusick 59665789Smckusick /* 59767377Smkm * Get Symbolic Link. 59865789Smckusick */ 59965789Smckusick static RRIP_TABLE rrip_table_getsymname[] = { 60065855Smckusick { "SL", cd9660_rrip_slink, 0, ISO_SUSP_SLINK }, 60165855Smckusick { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG }, 60265855Smckusick { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT }, 60365855Smckusick { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP }, 60465789Smckusick { "", 0, 0, 0 } 60565789Smckusick }; 60665789Smckusick 60765789Smckusick int 60865855Smckusick cd9660_rrip_getsymname(isodir,outbuf,outlen,imp) 60965789Smckusick struct iso_directory_record *isodir; 61065789Smckusick char *outbuf; 61165789Smckusick u_short *outlen; 61265789Smckusick struct iso_mnt *imp; 61365789Smckusick { 61465789Smckusick ISO_RRIP_ANALYZE analyze; 61565789Smckusick 61665789Smckusick analyze.outbuf = outbuf; 617*67699Smckusick analyze.outlen = outlen; 61865789Smckusick *outlen = 0; 61965789Smckusick analyze.maxlen = MAXPATHLEN; 62065789Smckusick analyze.cont = 1; /* don't start with a slash */ 62165789Smckusick analyze.imp = imp; 62265789Smckusick analyze.fields = ISO_SUSP_SLINK; 62365789Smckusick 62465855Smckusick return (cd9660_rrip_loop(isodir,&analyze,rrip_table_getsymname)&ISO_SUSP_SLINK); 62565789Smckusick } 62665789Smckusick 62765789Smckusick static RRIP_TABLE rrip_table_extref[] = { 62865855Smckusick { "ER", cd9660_rrip_extref, 0, ISO_SUSP_EXTREF }, 62965855Smckusick { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT }, 63065855Smckusick { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP }, 63165789Smckusick { "", 0, 0, 0 } 63265789Smckusick }; 63365789Smckusick 63465789Smckusick /* 63565789Smckusick * Check for Rock Ridge Extension and return offset of its fields. 63667377Smkm * Note: We insist on the ER field. 63765789Smckusick */ 63865789Smckusick int 63965855Smckusick cd9660_rrip_offset(isodir,imp) 64065789Smckusick struct iso_directory_record *isodir; 64165789Smckusick struct iso_mnt *imp; 64265789Smckusick { 64365789Smckusick ISO_RRIP_OFFSET *p; 64465789Smckusick ISO_RRIP_ANALYZE analyze; 64565789Smckusick 64665789Smckusick imp->rr_skip0 = 0; 64765789Smckusick p = (ISO_RRIP_OFFSET *)(isodir->name + 1); 64865789Smckusick if (bcmp(p,"SP\7\1\276\357",6)) { 64965789Smckusick /* Maybe, it's a CDROM XA disc? */ 65065789Smckusick imp->rr_skip0 = 15; 65165789Smckusick p = (ISO_RRIP_OFFSET *)((char *)p + 15); 65265789Smckusick if (bcmp(p,"SP\7\1\276\357",6)) 65365789Smckusick return -1; 65465789Smckusick } 65565789Smckusick 65665789Smckusick analyze.imp = imp; 65765789Smckusick analyze.fields = ISO_SUSP_EXTREF; 65865855Smckusick if (!(cd9660_rrip_loop(isodir,&analyze,rrip_table_extref)&ISO_SUSP_EXTREF)) 65965789Smckusick return -1; 66065789Smckusick 66165789Smckusick return isonum_711(p->skip); 66265789Smckusick } 663