123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775 |
- /* $OpenBSD: cd9660_rrip.c,v 1.13 2015/03/14 03:38:50 jsg Exp $ */
- /* $NetBSD: cd9660_rrip.c,v 1.17 1997/01/24 00:27:32 cgd Exp $ */
- /*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley
- * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
- * Support code is derived from software contributed to Berkeley
- * by Atsushi Murai (amurai@spec.co.jp).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)cd9660_rrip.c 8.6 (Berkeley) 12/5/94
- */
- #include <sys/param.h>
- #include <sys/systm.h>
- #include <sys/namei.h>
- #include <sys/buf.h>
- #include <sys/vnode.h>
- #include <sys/lock.h>
- #include <sys/mount.h>
- #include <sys/kernel.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <isofs/cd9660/iso.h>
- #include <isofs/cd9660/cd9660_extern.h>
- #include <isofs/cd9660/cd9660_node.h>
- #include <isofs/cd9660/cd9660_rrip.h>
- #include <isofs/cd9660/iso_rrip.h>
- typedef struct {
- char type[2];
- int (*func)(void *, ISO_RRIP_ANALYZE *);
- void (*func2)(void *, ISO_RRIP_ANALYZE *);
- int result;
- } RRIP_TABLE;
- static int cd9660_rrip_attr(void *, ISO_RRIP_ANALYZE *);
- static void cd9660_rrip_defattr(void *, ISO_RRIP_ANALYZE *);
- static int cd9660_rrip_slink(void *, ISO_RRIP_ANALYZE *);
- static int cd9660_rrip_altname(void *, ISO_RRIP_ANALYZE *);
- static void cd9660_rrip_defname(void *, ISO_RRIP_ANALYZE *);
- static int cd9660_rrip_pclink(void *, ISO_RRIP_ANALYZE *);
- static int cd9660_rrip_reldir(void *, ISO_RRIP_ANALYZE *);
- static int cd9660_rrip_tstamp(void *, ISO_RRIP_ANALYZE *);
- static void cd9660_rrip_deftstamp(void *, ISO_RRIP_ANALYZE *);
- static int cd9660_rrip_device(void *, ISO_RRIP_ANALYZE *);
- static int cd9660_rrip_idflag(void *, ISO_RRIP_ANALYZE *);
- static int cd9660_rrip_cont(void *, ISO_RRIP_ANALYZE *);
- static int cd9660_rrip_stop(void *, ISO_RRIP_ANALYZE *);
- static int cd9660_rrip_extref(void *, ISO_RRIP_ANALYZE *);
- static int cd9660_rrip_loop(struct iso_directory_record *,
- ISO_RRIP_ANALYZE *, RRIP_TABLE *);
- /*
- * POSIX file attribute
- */
- static int
- cd9660_rrip_attr(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- ISO_RRIP_ATTR *p = v;
- ana->inop->inode.iso_mode = isonum_733(p->mode);
- ana->inop->inode.iso_uid = isonum_733(p->uid);
- ana->inop->inode.iso_gid = isonum_733(p->gid);
- ana->inop->inode.iso_links = isonum_733(p->links);
- ana->fields &= ~ISO_SUSP_ATTR;
- return (ISO_SUSP_ATTR);
- }
- static void
- cd9660_rrip_defattr(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- struct iso_directory_record *isodir = v;
- /* But this is a required field! */
- printf("RRIP without PX field?\n");
- cd9660_defattr(isodir, ana->inop, NULL);
- }
- /*
- * Symbolic Links
- */
- static int
- cd9660_rrip_slink(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- ISO_RRIP_SLINK *p = v;
- register ISO_RRIP_SLINK_COMPONENT *pcomp;
- register ISO_RRIP_SLINK_COMPONENT *pcompe;
- int len, wlen, cont;
- char *outbuf, *inbuf;
-
- pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component;
- pcompe =
- (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length));
- len = *ana->outlen;
- outbuf = ana->outbuf;
- cont = ana->cont;
-
- /*
- * Gathering a Symbolic name from each component with path
- */
- for (; pcomp < pcompe;
- pcomp = (ISO_RRIP_SLINK_COMPONENT *)
- ((char *)pcomp + ISO_RRIP_SLSIZ + isonum_711(pcomp->clen))) {
-
- if (!cont) {
- if (len < ana->maxlen) {
- len++;
- *outbuf++ = '/';
- }
- }
- cont = 0;
-
- inbuf = "..";
- wlen = 0;
-
- switch (*pcomp->cflag) {
-
- case ISO_SUSP_CFLAG_CURRENT:
- /* Inserting Current */
- wlen = 1;
- break;
-
- case ISO_SUSP_CFLAG_PARENT:
- /* Inserting Parent */
- wlen = 2;
- break;
-
- case ISO_SUSP_CFLAG_ROOT:
- /* Inserting slash for ROOT */
- /* start over from beginning(?) */
- outbuf -= len;
- len = 0;
- break;
-
- case ISO_SUSP_CFLAG_VOLROOT:
- /* Inserting a mount point i.e. "/cdrom" */
- /* same as above */
- outbuf -= len;
- len = 0;
- inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname;
- wlen = strlen(inbuf);
- break;
-
- case ISO_SUSP_CFLAG_HOST:
- /* Inserting hostname i.e. "kurt.tools.de" */
- inbuf = hostname;
- wlen = hostnamelen;
- break;
-
- case ISO_SUSP_CFLAG_CONTINUE:
- cont = 1;
- /* FALLTHROUGH */
- case 0:
- /* Inserting component */
- wlen = isonum_711(pcomp->clen);
- inbuf = pcomp->name;
- break;
- default:
- printf("RRIP with incorrect flags?");
- wlen = ana->maxlen + 1;
- break;
- }
-
- if (len + wlen > ana->maxlen) {
- /* indicate error to caller */
- ana->cont = 1;
- ana->fields = 0;
- ana->outbuf -= *ana->outlen;
- *ana->outlen = 0;
- return (0);
- }
-
- bcopy(inbuf, outbuf, wlen);
- outbuf += wlen;
- len += wlen;
- }
- ana->outbuf = outbuf;
- *ana->outlen = len;
- ana->cont = cont;
-
- if (!isonum_711(p->flags)) {
- ana->fields &= ~ISO_SUSP_SLINK;
- return (ISO_SUSP_SLINK);
- }
- return (0);
- }
- /*
- * Alternate name
- */
- static int
- cd9660_rrip_altname(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- ISO_RRIP_ALTNAME *p = v;
- char *inbuf;
- int wlen;
- int cont;
-
- inbuf = "..";
- wlen = 0;
- cont = 0;
-
- switch (*p->flags) {
- case ISO_SUSP_CFLAG_CURRENT:
- /* Inserting Current */
- wlen = 1;
- break;
-
- case ISO_SUSP_CFLAG_PARENT:
- /* Inserting Parent */
- wlen = 2;
- break;
-
- case ISO_SUSP_CFLAG_HOST:
- /* Inserting hostname i.e. "kurt.tools.de" */
- inbuf = hostname;
- wlen = hostnamelen;
- break;
-
- case ISO_SUSP_CFLAG_CONTINUE:
- cont = 1;
- /* FALLTHROUGH */
- case 0:
- /* Inserting component */
- wlen = isonum_711(p->h.length) - 5;
- inbuf = (char *)p + 5;
- break;
-
- default:
- printf("RRIP with incorrect NM flags?\n");
- wlen = ana->maxlen + 1;
- break;
- }
-
- if ((*ana->outlen += wlen) > ana->maxlen) {
- /* treat as no name field */
- ana->fields &= ~ISO_SUSP_ALTNAME;
- ana->outbuf -= *ana->outlen - wlen;
- *ana->outlen = 0;
- return (0);
- }
-
- bcopy(inbuf, ana->outbuf, wlen);
- ana->outbuf += wlen;
-
- if (!cont) {
- ana->fields &= ~ISO_SUSP_ALTNAME;
- return (ISO_SUSP_ALTNAME);
- }
- return (0);
- }
- static void
- cd9660_rrip_defname(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- struct iso_directory_record *isodir = v;
- strlcpy(ana->outbuf, "..", ana->maxlen - *ana->outlen);
- switch (*isodir->name) {
- default:
- isofntrans(isodir->name, isonum_711(isodir->name_len),
- ana->outbuf, ana->outlen, 1,
- isonum_711(isodir->flags) & 4, ana->imp->joliet_level);
- break;
- case 0:
- *ana->outlen = 1;
- break;
- case 1:
- *ana->outlen = 2;
- break;
- }
- }
- /*
- * Parent or Child Link
- */
- static int
- cd9660_rrip_pclink(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- ISO_RRIP_CLINK *p = v;
- *ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift;
- ana->fields &= ~(ISO_SUSP_CLINK | ISO_SUSP_PLINK);
- return (*p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK);
- }
- /*
- * Relocated directory
- */
- /*ARGSUSED*/
- static int
- cd9660_rrip_reldir(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- /* special hack to make caller aware of RE field */
- *ana->outlen = 0;
- ana->fields = 0;
- return (ISO_SUSP_RELDIR | ISO_SUSP_ALTNAME | ISO_SUSP_CLINK |
- ISO_SUSP_PLINK);
- }
- static int
- cd9660_rrip_tstamp(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- ISO_RRIP_TSTAMP *p = v;
- u_char *ptime;
-
- ptime = p->time;
-
- /* Check a format of time stamp (7bytes/17bytes) */
- if (!(*p->flags & ISO_SUSP_TSTAMP_FORM17)) {
- if (*p->flags & ISO_SUSP_TSTAMP_CREAT)
- ptime += 7;
-
- if (*p->flags & ISO_SUSP_TSTAMP_MODIFY) {
- cd9660_tstamp_conv7(ptime,
- &ana->inop->inode.iso_mtime);
- ptime += 7;
- } else
- bzero(&ana->inop->inode.iso_mtime,
- sizeof(struct timespec));
-
- if (*p->flags & ISO_SUSP_TSTAMP_ACCESS) {
- cd9660_tstamp_conv7(ptime,
- &ana->inop->inode.iso_atime);
- ptime += 7;
- } else
- ana->inop->inode.iso_atime =
- ana->inop->inode.iso_mtime;
-
- if (*p->flags & ISO_SUSP_TSTAMP_ATTR)
- cd9660_tstamp_conv7(ptime,
- &ana->inop->inode.iso_ctime);
- else
- ana->inop->inode.iso_ctime =
- ana->inop->inode.iso_mtime;
-
- } else {
- if (*p->flags & ISO_SUSP_TSTAMP_CREAT)
- ptime += 17;
-
- if (*p->flags & ISO_SUSP_TSTAMP_MODIFY) {
- cd9660_tstamp_conv17(ptime,
- &ana->inop->inode.iso_mtime);
- ptime += 17;
- } else
- bzero(&ana->inop->inode.iso_mtime,
- sizeof(struct timespec));
-
- if (*p->flags & ISO_SUSP_TSTAMP_ACCESS) {
- cd9660_tstamp_conv17(ptime,
- &ana->inop->inode.iso_atime);
- ptime += 17;
- } else
- ana->inop->inode.iso_atime =
- ana->inop->inode.iso_mtime;
-
- if (*p->flags & ISO_SUSP_TSTAMP_ATTR)
- cd9660_tstamp_conv17(ptime,
- &ana->inop->inode.iso_ctime);
- else
- ana->inop->inode.iso_ctime =
- ana->inop->inode.iso_mtime;
-
- }
- ana->fields &= ~ISO_SUSP_TSTAMP;
- return (ISO_SUSP_TSTAMP);
- }
- static void
- cd9660_rrip_deftstamp(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- struct iso_directory_record *isodir = v;
- cd9660_deftstamp(isodir, ana->inop, NULL);
- }
- /*
- * POSIX device modes
- */
- static int
- cd9660_rrip_device(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- ISO_RRIP_DEVICE *p = v;
- u_int high, low;
-
- high = isonum_733(p->dev_t_high);
- low = isonum_733(p->dev_t_low);
-
- if (high == 0)
- ana->inop->inode.iso_rdev = makedev(major(low), minor(low));
- else
- ana->inop->inode.iso_rdev = makedev(high, minor(low));
- ana->fields &= ~ISO_SUSP_DEVICE;
- return (ISO_SUSP_DEVICE);
- }
- /*
- * Flag indicating
- */
- static int
- cd9660_rrip_idflag(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- ISO_RRIP_IDFLAG *p = v;
- /* don't touch high bits */
- ana->fields &= isonum_711(p->flags) | ~0xff;
- /* special handling of RE field */
- if (ana->fields & ISO_SUSP_RELDIR)
- return (cd9660_rrip_reldir(p, ana));
-
- return (ISO_SUSP_IDFLAG);
- }
- /*
- * Continuation pointer
- */
- static int
- cd9660_rrip_cont(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- ISO_RRIP_CONT *p = v;
- ana->iso_ce_blk = isonum_733(p->location);
- ana->iso_ce_off = isonum_733(p->offset);
- ana->iso_ce_len = isonum_733(p->length);
- return (ISO_SUSP_CONT);
- }
- /*
- * System Use end
- */
- static int
- cd9660_rrip_stop(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- return (ISO_SUSP_STOP);
- }
- /*
- * Extension reference
- */
- static int
- cd9660_rrip_extref(v, ana)
- void *v;
- ISO_RRIP_ANALYZE *ana;
- {
- ISO_RRIP_EXTREF *p = v;
- if (isonum_711(p->version) != 1)
- return (0);
- if (isonum_711(p->len_id) != 9 &&
- isonum_711(p->len_id) != 10)
- return (0);
- if (isonum_711(p->len_id) == 9 &&
- bcmp((char *)p + 8, "IEEE_1282", 9))
- return (0);
- if (isonum_711(p->len_id) == 10 &&
- bcmp((char *)p + 8, "IEEE_P1282", 10) &&
- bcmp((char *)p + 8, "RRIP_1991A", 10))
- return (0);
- ana->fields &= ~ISO_SUSP_EXTREF;
- return (ISO_SUSP_EXTREF);
- }
- static int
- cd9660_rrip_loop(isodir, ana, table)
- struct iso_directory_record *isodir;
- ISO_RRIP_ANALYZE *ana;
- RRIP_TABLE *table;
- {
- register RRIP_TABLE *ptable;
- register ISO_SUSP_HEADER *phead;
- register ISO_SUSP_HEADER *pend;
- struct buf *bp = NULL;
- char *pwhead;
- u_char c;
- int result;
-
- /*
- * Note: If name length is odd,
- * it will be padded by 1 byte after the name
- */
- pwhead = isodir->name + isonum_711(isodir->name_len);
- if (!(isonum_711(isodir->name_len) & 1))
- pwhead++;
- isochar(isodir->name, pwhead, ana->imp->joliet_level, &c);
-
- /* If it's not the '.' entry of the root dir obey SP field */
- if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent)
- pwhead += ana->imp->rr_skip;
- else
- pwhead += ana->imp->rr_skip0;
-
- phead = (ISO_SUSP_HEADER *)pwhead;
- pend =
- (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length));
-
- result = 0;
- while (1) {
- ana->iso_ce_len = 0;
- /*
- * Note: "pend" should be more than one SUSP header
- */
- while (pend >= phead + 1) {
- if (isonum_711(phead->version) == 1) {
- for (ptable = table; ptable->func; ptable++) {
- if (*phead->type == *ptable->type &&
- phead->type[1] == ptable->type[1])
- {
- result |=
- ptable->func(phead, ana);
- break;
- }
- }
- if (!ana->fields)
- break;
- }
- if (result & ISO_SUSP_STOP) {
- result &= ~ISO_SUSP_STOP;
- break;
- }
- /* plausibility check */
- if (isonum_711(phead->length) < sizeof(*phead))
- break;
- /*
- * move to next SUSP
- * Hopefully this works with newer versions, too
- */
- phead = (ISO_SUSP_HEADER *)
- ((char *)phead + isonum_711(phead->length));
- }
-
- if (ana->fields && ana->iso_ce_len) {
- if (ana->iso_ce_blk >= ana->imp->volume_space_size ||
- ana->iso_ce_off + ana->iso_ce_len >
- ana->imp->logical_block_size ||
- bread(ana->imp->im_devvp, ana->iso_ce_blk <<
- (ana->imp->im_bshift - DEV_BSHIFT),
- ana->imp->logical_block_size, &bp))
- /* what to do now? */
- break;
- phead =
- (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off);
- pend = (ISO_SUSP_HEADER *)
- ((char *)phead + ana->iso_ce_len);
- } else
- break;
- }
- if (bp)
- brelse(bp);
- /*
- * If we don't find the Basic SUSP stuffs, just set default value
- * (attribute/time stamp)
- */
- for (ptable = table; ptable->func2; ptable++)
- if (!(ptable->result & result))
- ptable->func2(isodir, ana);
-
- return (result);
- }
- /*
- * Get Attributes.
- */
- static RRIP_TABLE rrip_table_analyze[] = {
- { "PX", cd9660_rrip_attr, cd9660_rrip_defattr,
- ISO_SUSP_ATTR },
- { "TF", cd9660_rrip_tstamp, cd9660_rrip_deftstamp,
- ISO_SUSP_TSTAMP },
- { "PN", cd9660_rrip_device, 0,
- ISO_SUSP_DEVICE },
- { "RR", cd9660_rrip_idflag, 0,
- ISO_SUSP_IDFLAG },
- { "CE", cd9660_rrip_cont, 0,
- ISO_SUSP_CONT },
- { "ST", cd9660_rrip_stop, 0,
- ISO_SUSP_STOP },
- { "", 0, 0,
- 0 }
- };
- int
- cd9660_rrip_analyze(isodir, inop, imp)
- struct iso_directory_record *isodir;
- struct iso_node *inop;
- struct iso_mnt *imp;
- {
- ISO_RRIP_ANALYZE analyze;
-
- analyze.inop = inop;
- analyze.imp = imp;
- analyze.fields = ISO_SUSP_ATTR | ISO_SUSP_TSTAMP | ISO_SUSP_DEVICE;
-
- return (cd9660_rrip_loop(isodir, &analyze, rrip_table_analyze));
- }
- /*
- * Get Alternate Name.
- */
- static RRIP_TABLE rrip_table_getname[] = {
- { "NM", cd9660_rrip_altname, cd9660_rrip_defname,
- ISO_SUSP_ALTNAME },
- { "CL", cd9660_rrip_pclink, 0,
- ISO_SUSP_CLINK|ISO_SUSP_PLINK },
- { "PL", cd9660_rrip_pclink, 0,
- ISO_SUSP_CLINK|ISO_SUSP_PLINK },
- { "RE", cd9660_rrip_reldir, 0,
- ISO_SUSP_RELDIR },
- { "RR", cd9660_rrip_idflag, 0,
- ISO_SUSP_IDFLAG },
- { "CE", cd9660_rrip_cont, 0,
- ISO_SUSP_CONT },
- { "ST", cd9660_rrip_stop, 0,
- ISO_SUSP_STOP },
- { "", 0, 0,
- 0 }
- };
- int
- cd9660_rrip_getname(isodir, outbuf, outlen, inump, imp)
- struct iso_directory_record *isodir;
- char *outbuf;
- u_short *outlen;
- cdino_t *inump;
- struct iso_mnt *imp;
- {
- ISO_RRIP_ANALYZE analyze;
- RRIP_TABLE *tab;
- u_char c;
-
- analyze.outbuf = outbuf;
- analyze.outlen = outlen;
- analyze.maxlen = NAME_MAX;
- analyze.inump = inump;
- analyze.imp = imp;
- analyze.fields = ISO_SUSP_ALTNAME | ISO_SUSP_RELDIR | ISO_SUSP_CLINK |
- ISO_SUSP_PLINK;
- *outlen = 0;
-
- isochar(isodir->name, isodir->name + isonum_711(isodir->name_len),
- imp->joliet_level, &c);
- tab = rrip_table_getname;
- if (c == 0 || c == 1) {
- cd9660_rrip_defname(isodir, &analyze);
-
- analyze.fields &= ~ISO_SUSP_ALTNAME;
- tab++;
- }
-
- return (cd9660_rrip_loop(isodir, &analyze, tab));
- }
- /*
- * Get Symbolic Link.
- */
- static RRIP_TABLE rrip_table_getsymname[] = {
- { "SL", cd9660_rrip_slink, 0, ISO_SUSP_SLINK },
- { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG },
- { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
- { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
- { "", 0, 0, 0 }
- };
- int
- cd9660_rrip_getsymname(isodir, outbuf, outlen, imp)
- struct iso_directory_record *isodir;
- char *outbuf;
- u_short *outlen;
- struct iso_mnt *imp;
- {
- ISO_RRIP_ANALYZE analyze;
-
- analyze.outbuf = outbuf;
- analyze.outlen = outlen;
- *outlen = 0;
- analyze.maxlen = MAXPATHLEN;
- analyze.cont = 1; /* don't start with a slash */
- analyze.imp = imp;
- analyze.fields = ISO_SUSP_SLINK;
-
- return (cd9660_rrip_loop(isodir, &analyze, rrip_table_getsymname) &
- ISO_SUSP_SLINK);
- }
- static RRIP_TABLE rrip_table_extref[] = {
- { "ER", cd9660_rrip_extref, 0, ISO_SUSP_EXTREF },
- { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
- { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
- { "", 0, 0, 0 }
- };
- /*
- * Check for Rock Ridge Extension and return offset of its fields.
- * Note: We insist on the ER field.
- */
- int
- cd9660_rrip_offset(isodir, imp)
- struct iso_directory_record *isodir;
- struct iso_mnt *imp;
- {
- ISO_RRIP_OFFSET *p;
- ISO_RRIP_ANALYZE analyze;
-
- imp->rr_skip0 = 0;
- p = (ISO_RRIP_OFFSET *)(isodir->name + 1);
- if (bcmp(p, "SP\7\1\276\357", 6)) {
- /* Maybe, it's a CDROM XA disc? */
- imp->rr_skip0 = 15;
- p = (ISO_RRIP_OFFSET *)((char *)p + 15);
- if (bcmp(p, "SP\7\1\276\357", 6))
- return (-1);
- }
-
- analyze.imp = imp;
- analyze.fields = ISO_SUSP_EXTREF;
- if (!(cd9660_rrip_loop(isodir, &analyze, rrip_table_extref) &
- ISO_SUSP_EXTREF))
- return (-1);
-
- return (isonum_711(p->skip));
- }
|