root/isofs/cd9660/cd9660_rrip.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. RRIP_TABLE
  2. cd9660_rrip_attr
  3. cd9660_rrip_defattr
  4. cd9660_rrip_slink
  5. cd9660_rrip_altname
  6. cd9660_rrip_defname
  7. cd9660_rrip_pclink
  8. cd9660_rrip_reldir
  9. cd9660_rrip_tstamp
  10. cd9660_rrip_deftstamp
  11. cd9660_rrip_device
  12. cd9660_rrip_idflag
  13. cd9660_rrip_cont
  14. cd9660_rrip_stop
  15. cd9660_rrip_extref
  16. cd9660_rrip_loop
  17. cd9660_rrip_analyze
  18. cd9660_rrip_getname
  19. cd9660_rrip_getsymname
  20. cd9660_rrip_offset

    1 /*      $OpenBSD: cd9660_rrip.c,v 1.9 2007/02/14 00:53:48 jsg Exp $     */
    2 /*      $NetBSD: cd9660_rrip.c,v 1.17 1997/01/24 00:27:32 cgd Exp $     */
    3 
    4 /*-
    5  * Copyright (c) 1993, 1994
    6  *      The Regents of the University of California.  All rights reserved.
    7  *
    8  * This code is derived from software contributed to Berkeley
    9  * by Pace Willisson (pace@blitz.com).  The Rock Ridge Extension
   10  * Support code is derived from software contributed to Berkeley
   11  * by Atsushi Murai (amurai@spec.co.jp).
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. Neither the name of the University nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  *      @(#)cd9660_rrip.c       8.6 (Berkeley) 12/5/94
   38  */
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/namei.h>
   43 #include <sys/buf.h>
   44 #include <sys/file.h>
   45 #include <sys/vnode.h>
   46 #include <sys/mount.h>
   47 #include <sys/kernel.h>
   48 #include <sys/stat.h>
   49 #include <sys/types.h>
   50 
   51 #include <sys/time.h>
   52 
   53 #include <isofs/cd9660/iso.h>
   54 #include <isofs/cd9660/cd9660_extern.h>
   55 #include <isofs/cd9660/cd9660_node.h>
   56 #include <isofs/cd9660/cd9660_rrip.h>
   57 #include <isofs/cd9660/iso_rrip.h>
   58 
   59 typedef struct {
   60         char type[2];
   61         int (*func)(void *, ISO_RRIP_ANALYZE *);
   62         void (*func2)(void *, ISO_RRIP_ANALYZE *);
   63         int result;
   64 } RRIP_TABLE;
   65 
   66 static int cd9660_rrip_attr(void *, ISO_RRIP_ANALYZE *);
   67 static void cd9660_rrip_defattr(void *, ISO_RRIP_ANALYZE *);
   68 static int cd9660_rrip_slink(void *, ISO_RRIP_ANALYZE *);
   69 static int cd9660_rrip_altname(void *, ISO_RRIP_ANALYZE *);
   70 static void cd9660_rrip_defname(void *, ISO_RRIP_ANALYZE *);
   71 static int cd9660_rrip_pclink(void *, ISO_RRIP_ANALYZE *);
   72 static int cd9660_rrip_reldir(void *, ISO_RRIP_ANALYZE *);
   73 static int cd9660_rrip_tstamp(void *, ISO_RRIP_ANALYZE *);
   74 static void cd9660_rrip_deftstamp(void *, ISO_RRIP_ANALYZE *);
   75 static int cd9660_rrip_device(void *, ISO_RRIP_ANALYZE *);
   76 static int cd9660_rrip_idflag(void *, ISO_RRIP_ANALYZE *);
   77 static int cd9660_rrip_cont(void *, ISO_RRIP_ANALYZE *);
   78 static int cd9660_rrip_stop(void *, ISO_RRIP_ANALYZE *);
   79 static int cd9660_rrip_extref(void *, ISO_RRIP_ANALYZE *);
   80 static int cd9660_rrip_loop(struct iso_directory_record *,
   81     ISO_RRIP_ANALYZE *, RRIP_TABLE *);
   82 /*
   83  * POSIX file attribute
   84  */
   85 static int
   86 cd9660_rrip_attr(v, ana)
   87         void *v;
   88         ISO_RRIP_ANALYZE *ana;
   89 {
   90         ISO_RRIP_ATTR *p = v;
   91 
   92         ana->inop->inode.iso_mode = isonum_733(p->mode);
   93         ana->inop->inode.iso_uid = isonum_733(p->uid);
   94         ana->inop->inode.iso_gid = isonum_733(p->gid);
   95         ana->inop->inode.iso_links = isonum_733(p->links);
   96         ana->fields &= ~ISO_SUSP_ATTR;
   97         return (ISO_SUSP_ATTR);
   98 }
   99 
  100 static void
  101 cd9660_rrip_defattr(v, ana)
  102         void *v;
  103         ISO_RRIP_ANALYZE *ana;
  104 {
  105         struct iso_directory_record *isodir = v;
  106 
  107         /* But this is a required field! */
  108         printf("RRIP without PX field?\n");
  109         cd9660_defattr(isodir, ana->inop, NULL);
  110 }
  111 
  112 /*
  113  * Symbolic Links
  114  */
  115 static int
  116 cd9660_rrip_slink(v, ana)
  117         void *v;
  118         ISO_RRIP_ANALYZE *ana;
  119 {
  120         ISO_RRIP_SLINK  *p = v;
  121         register ISO_RRIP_SLINK_COMPONENT *pcomp;
  122         register ISO_RRIP_SLINK_COMPONENT *pcompe;
  123         int len, wlen, cont;
  124         char *outbuf, *inbuf;
  125         
  126         pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component;
  127         pcompe =
  128             (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length));
  129         len = *ana->outlen;
  130         outbuf = ana->outbuf;
  131         cont = ana->cont;
  132         
  133         /*
  134          * Gathering a Symbolic name from each component with path
  135          */
  136         for (; pcomp < pcompe;
  137             pcomp = (ISO_RRIP_SLINK_COMPONENT *)
  138             ((char *)pcomp + ISO_RRIP_SLSIZ + isonum_711(pcomp->clen))) {
  139                 
  140                 if (!cont) {
  141                         if (len < ana->maxlen) {
  142                                 len++;
  143                                 *outbuf++ = '/';
  144                         }
  145                 }
  146                 cont = 0;
  147                 
  148                 inbuf = "..";
  149                 wlen = 0;
  150                 
  151                 switch (*pcomp->cflag) {
  152                         
  153                 case ISO_SUSP_CFLAG_CURRENT:
  154                         /* Inserting Current */
  155                         wlen = 1;
  156                         break;
  157                         
  158                 case ISO_SUSP_CFLAG_PARENT:
  159                         /* Inserting Parent */
  160                         wlen = 2;
  161                         break;
  162                         
  163                 case ISO_SUSP_CFLAG_ROOT:
  164                         /* Inserting slash for ROOT */
  165                         /* start over from beginning(?) */
  166                         outbuf -= len;
  167                         len = 0;
  168                         break;
  169                         
  170                 case ISO_SUSP_CFLAG_VOLROOT:
  171                         /* Inserting a mount point i.e. "/cdrom" */
  172                         /* same as above */
  173                         outbuf -= len;
  174                         len = 0;
  175                         inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname;
  176                         wlen = strlen(inbuf);
  177                         break;
  178                         
  179                 case ISO_SUSP_CFLAG_HOST:
  180                         /* Inserting hostname i.e. "kurt.tools.de" */
  181                         inbuf = hostname;
  182                         wlen = hostnamelen;
  183                         break;
  184                         
  185                 case ISO_SUSP_CFLAG_CONTINUE:
  186                         cont = 1;
  187                         /* FALLTHROUGH */
  188                 case 0:
  189                         /* Inserting component */
  190                         wlen = isonum_711(pcomp->clen);
  191                         inbuf = pcomp->name;
  192                         break;
  193                 default:
  194                         printf("RRIP with incorrect flags?");
  195                         wlen = ana->maxlen + 1;
  196                         break;
  197                 }
  198                 
  199                 if (len + wlen > ana->maxlen) {
  200                         /* indicate error to caller */
  201                         ana->cont = 1;
  202                         ana->fields = 0;
  203                         ana->outbuf -= *ana->outlen;
  204                         *ana->outlen = 0;
  205                         return (0);
  206                 }
  207                 
  208                 bcopy(inbuf, outbuf, wlen);
  209                 outbuf += wlen;
  210                 len += wlen;
  211         }
  212         ana->outbuf = outbuf;
  213         *ana->outlen = len;
  214         ana->cont = cont;
  215         
  216         if (!isonum_711(p->flags)) {
  217                 ana->fields &= ~ISO_SUSP_SLINK;
  218                 return (ISO_SUSP_SLINK);
  219         }
  220         return (0);
  221 }
  222 
  223 /*
  224  * Alternate name
  225  */
  226 static int
  227 cd9660_rrip_altname(v, ana)
  228         void *v;
  229         ISO_RRIP_ANALYZE *ana;
  230 {
  231         ISO_RRIP_ALTNAME *p = v;
  232         char *inbuf;
  233         int wlen;
  234         int cont;
  235         
  236         inbuf = "..";
  237         wlen = 0;
  238         cont = 0;
  239         
  240         switch (*p->flags) {
  241         case ISO_SUSP_CFLAG_CURRENT:
  242                 /* Inserting Current */
  243                 wlen = 1;
  244                 break;
  245                 
  246         case ISO_SUSP_CFLAG_PARENT:
  247                 /* Inserting Parent */
  248                 wlen = 2;
  249                 break;
  250                 
  251         case ISO_SUSP_CFLAG_HOST:
  252                 /* Inserting hostname i.e. "kurt.tools.de" */
  253                 inbuf = hostname;
  254                 wlen = hostnamelen;
  255                 break;
  256                 
  257         case ISO_SUSP_CFLAG_CONTINUE:
  258                 cont = 1;
  259                 /* FALLTHROUGH */
  260         case 0:
  261                 /* Inserting component */
  262                 wlen = isonum_711(p->h.length) - 5;
  263                 inbuf = (char *)p + 5;
  264                 break;
  265                 
  266         default:
  267                 printf("RRIP with incorrect NM flags?\n");
  268                 wlen = ana->maxlen + 1;
  269                 break;
  270         }
  271         
  272         if ((*ana->outlen += wlen) > ana->maxlen) {
  273                 /* treat as no name field */
  274                 ana->fields &= ~ISO_SUSP_ALTNAME;
  275                 ana->outbuf -= *ana->outlen - wlen;
  276                 *ana->outlen = 0;
  277                 return (0);
  278         }
  279         
  280         bcopy(inbuf, ana->outbuf, wlen);
  281         ana->outbuf += wlen;
  282         
  283         if (!cont) {
  284                 ana->fields &= ~ISO_SUSP_ALTNAME;
  285                 return (ISO_SUSP_ALTNAME);
  286         }
  287         return (0);
  288 }
  289 
  290 static void
  291 cd9660_rrip_defname(v, ana)
  292         void *v;
  293         ISO_RRIP_ANALYZE *ana;
  294 {
  295         struct iso_directory_record *isodir = v;
  296 
  297         strlcpy(ana->outbuf, "..", ana->maxlen - *ana->outlen);
  298         switch (*isodir->name) {
  299         default:
  300                 isofntrans(isodir->name, isonum_711(isodir->name_len),
  301                     ana->outbuf, ana->outlen, 1,
  302                     isonum_711(isodir->flags) & 4, ana->imp->joliet_level);
  303                 break;
  304         case 0:
  305                 *ana->outlen = 1;
  306                 break;
  307         case 1:
  308                 *ana->outlen = 2;
  309                 break;
  310         }
  311 }
  312 
  313 /*
  314  * Parent or Child Link
  315  */
  316 static int
  317 cd9660_rrip_pclink(v, ana)
  318         void *v;
  319         ISO_RRIP_ANALYZE *ana;
  320 {
  321         ISO_RRIP_CLINK  *p = v;
  322 
  323         *ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift;
  324         ana->fields &= ~(ISO_SUSP_CLINK | ISO_SUSP_PLINK);
  325         return (*p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK);
  326 }
  327 
  328 /*
  329  * Relocated directory
  330  */
  331 /*ARGSUSED*/
  332 static int
  333 cd9660_rrip_reldir(v, ana)
  334         void *v;
  335         ISO_RRIP_ANALYZE *ana;
  336 {
  337         /* special hack to make caller aware of RE field */
  338         *ana->outlen = 0;
  339         ana->fields = 0;
  340         return (ISO_SUSP_RELDIR | ISO_SUSP_ALTNAME | ISO_SUSP_CLINK |
  341             ISO_SUSP_PLINK);
  342 }
  343 
  344 static int
  345 cd9660_rrip_tstamp(v, ana)
  346         void *v;
  347         ISO_RRIP_ANALYZE *ana;
  348 {
  349         ISO_RRIP_TSTAMP *p = v;
  350         u_char *ptime;
  351         
  352         ptime = p->time;
  353         
  354         /* Check a format of time stamp (7bytes/17bytes) */
  355         if (!(*p->flags & ISO_SUSP_TSTAMP_FORM17)) {
  356                 if (*p->flags & ISO_SUSP_TSTAMP_CREAT)
  357                         ptime += 7;
  358                 
  359                 if (*p->flags & ISO_SUSP_TSTAMP_MODIFY) {
  360                         cd9660_tstamp_conv7(ptime,
  361                             &ana->inop->inode.iso_mtime);
  362                         ptime += 7;
  363                 } else
  364                         bzero(&ana->inop->inode.iso_mtime,
  365                             sizeof(struct timespec));
  366                 
  367                 if (*p->flags & ISO_SUSP_TSTAMP_ACCESS) {
  368                         cd9660_tstamp_conv7(ptime,
  369                             &ana->inop->inode.iso_atime);
  370                         ptime += 7;
  371                 } else
  372                         ana->inop->inode.iso_atime =
  373                             ana->inop->inode.iso_mtime;
  374                 
  375                 if (*p->flags & ISO_SUSP_TSTAMP_ATTR)
  376                         cd9660_tstamp_conv7(ptime,
  377                             &ana->inop->inode.iso_ctime);
  378                 else
  379                         ana->inop->inode.iso_ctime =
  380                             ana->inop->inode.iso_mtime;
  381                 
  382         } else {
  383                 if (*p->flags & ISO_SUSP_TSTAMP_CREAT)
  384                         ptime += 17;
  385                 
  386                 if (*p->flags & ISO_SUSP_TSTAMP_MODIFY) {
  387                         cd9660_tstamp_conv17(ptime,
  388                             &ana->inop->inode.iso_mtime);
  389                         ptime += 17;
  390                 } else
  391                         bzero(&ana->inop->inode.iso_mtime,
  392                             sizeof(struct timespec));
  393                 
  394                 if (*p->flags & ISO_SUSP_TSTAMP_ACCESS) {
  395                         cd9660_tstamp_conv17(ptime,
  396                             &ana->inop->inode.iso_atime);
  397                         ptime += 17;
  398                 } else
  399                         ana->inop->inode.iso_atime =
  400                             ana->inop->inode.iso_mtime;
  401                 
  402                 if (*p->flags & ISO_SUSP_TSTAMP_ATTR)
  403                         cd9660_tstamp_conv17(ptime,
  404                             &ana->inop->inode.iso_ctime);
  405                 else
  406                         ana->inop->inode.iso_ctime =
  407                             ana->inop->inode.iso_mtime;
  408                 
  409         }
  410         ana->fields &= ~ISO_SUSP_TSTAMP;
  411         return (ISO_SUSP_TSTAMP);
  412 }
  413 
  414 static void
  415 cd9660_rrip_deftstamp(v, ana)
  416         void *v;
  417         ISO_RRIP_ANALYZE *ana;
  418 {
  419         struct iso_directory_record  *isodir = v;
  420 
  421         cd9660_deftstamp(isodir, ana->inop, NULL);
  422 }
  423 
  424 /*
  425  * POSIX device modes
  426  */
  427 static int
  428 cd9660_rrip_device(v, ana)
  429         void *v;
  430         ISO_RRIP_ANALYZE *ana;
  431 {
  432         ISO_RRIP_DEVICE *p = v;
  433         u_int high, low;
  434         
  435         high = isonum_733(p->dev_t_high);
  436         low  = isonum_733(p->dev_t_low);
  437         
  438         if (high == 0)
  439                 ana->inop->inode.iso_rdev = makedev(major(low), minor(low));
  440         else
  441                 ana->inop->inode.iso_rdev = makedev(high, minor(low));
  442         ana->fields &= ~ISO_SUSP_DEVICE;
  443         return (ISO_SUSP_DEVICE);
  444 }
  445 
  446 /*
  447  * Flag indicating
  448  */
  449 static int
  450 cd9660_rrip_idflag(v, ana)
  451         void *v;
  452         ISO_RRIP_ANALYZE *ana;
  453 {
  454         ISO_RRIP_IDFLAG *p = v;
  455 
  456         /* don't touch high bits */
  457         ana->fields &= isonum_711(p->flags) | ~0xff;
  458         /* special handling of RE field */
  459         if (ana->fields & ISO_SUSP_RELDIR)
  460                 return (cd9660_rrip_reldir(p, ana));
  461         
  462         return (ISO_SUSP_IDFLAG);
  463 }
  464 
  465 /*
  466  * Continuation pointer
  467  */
  468 static int
  469 cd9660_rrip_cont(v, ana)
  470         void *v;
  471         ISO_RRIP_ANALYZE *ana;
  472 {
  473         ISO_RRIP_CONT *p = v;
  474 
  475         ana->iso_ce_blk = isonum_733(p->location);
  476         ana->iso_ce_off = isonum_733(p->offset);
  477         ana->iso_ce_len = isonum_733(p->length);
  478         return (ISO_SUSP_CONT);
  479 }
  480 
  481 /*
  482  * System Use end
  483  */
  484 static int
  485 cd9660_rrip_stop(v, ana)
  486         void *v;
  487         ISO_RRIP_ANALYZE *ana;
  488 {
  489         return (ISO_SUSP_STOP);
  490 }
  491 
  492 /*
  493  * Extension reference
  494  */
  495 static int
  496 cd9660_rrip_extref(v, ana)
  497         void *v;
  498         ISO_RRIP_ANALYZE *ana;
  499 {
  500         ISO_RRIP_EXTREF *p = v;
  501 
  502         if (isonum_711(p->version) != 1)
  503                 return (0);
  504         if (isonum_711(p->len_id) != 9 &&
  505             isonum_711(p->len_id) != 10)
  506                 return (0);
  507         if (isonum_711(p->len_id) == 9 &&
  508             bcmp((char *)p + 8, "IEEE_1282", 9))
  509                 return (0);
  510         if (isonum_711(p->len_id) == 10 &&
  511             bcmp((char *)p + 8, "IEEE_P1282", 10) &&
  512             bcmp((char *)p + 8, "RRIP_1991A", 10))
  513                 return (0);
  514         ana->fields &= ~ISO_SUSP_EXTREF;
  515         return (ISO_SUSP_EXTREF);
  516 }
  517 
  518 
  519 static int
  520 cd9660_rrip_loop(isodir, ana, table)
  521         struct iso_directory_record *isodir;
  522         ISO_RRIP_ANALYZE *ana;
  523         RRIP_TABLE *table;
  524 {
  525         register RRIP_TABLE *ptable;
  526         register ISO_SUSP_HEADER *phead;
  527         register ISO_SUSP_HEADER *pend;
  528         struct buf *bp = NULL;
  529         char *pwhead;
  530         u_char c;
  531         int result;
  532         
  533         /*
  534          * Note: If name length is odd,
  535          *       it will be padded by 1 byte after the name
  536          */
  537         pwhead = isodir->name + isonum_711(isodir->name_len);
  538         if (!(isonum_711(isodir->name_len) & 1))
  539                 pwhead++;
  540         isochar(isodir->name, pwhead, ana->imp->joliet_level, &c);
  541         
  542         /* If it's not the '.' entry of the root dir obey SP field */
  543         if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent)
  544                 pwhead += ana->imp->rr_skip;
  545         else
  546                 pwhead += ana->imp->rr_skip0;
  547         
  548         phead = (ISO_SUSP_HEADER *)pwhead;
  549         pend =
  550             (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length));
  551         
  552         result = 0;
  553         while (1) {
  554                 ana->iso_ce_len = 0;
  555                 /*
  556                  * Note: "pend" should be more than one SUSP header
  557                  */ 
  558                 while (pend >= phead + 1) {
  559                         if (isonum_711(phead->version) == 1) {
  560                                 for (ptable = table; ptable->func; ptable++) {
  561                                         if (*phead->type == *ptable->type &&
  562                                             phead->type[1] == ptable->type[1])
  563                                             {
  564                                                 result |=
  565                                                     ptable->func(phead, ana);
  566                                                 break;
  567                                         }
  568                                 }
  569                                 if (!ana->fields)
  570                                         break;
  571                         }
  572                         if (result & ISO_SUSP_STOP) {
  573                                 result &= ~ISO_SUSP_STOP;
  574                                 break;
  575                         }
  576                         /* plausibility check */
  577                         if (isonum_711(phead->length) < sizeof(*phead))
  578                                 break;
  579                         /*
  580                          * move to next SUSP
  581                          * Hopefully this works with newer versions, too
  582                          */
  583                         phead = (ISO_SUSP_HEADER *)
  584                             ((char *)phead + isonum_711(phead->length));
  585                 }
  586                 
  587                 if (ana->fields && ana->iso_ce_len) {
  588                         if (ana->iso_ce_blk >= ana->imp->volume_space_size ||
  589                             ana->iso_ce_off + ana->iso_ce_len >
  590                             ana->imp->logical_block_size ||
  591                             bread(ana->imp->im_devvp, ana->iso_ce_blk <<
  592                             (ana->imp->im_bshift - DEV_BSHIFT),
  593                             ana->imp->logical_block_size, NOCRED, &bp))
  594                                 /* what to do now? */
  595                                 break;
  596                         phead =
  597                             (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off);
  598                         pend = (ISO_SUSP_HEADER *)
  599                             ((char *)phead + ana->iso_ce_len);
  600                 } else
  601                         break;
  602         }
  603         if (bp)
  604                 brelse(bp);
  605         /*
  606          * If we don't find the Basic SUSP stuffs, just set default value
  607          *   (attribute/time stamp)
  608          */
  609         for (ptable = table; ptable->func2; ptable++)
  610                 if (!(ptable->result & result))
  611                         ptable->func2(isodir, ana);
  612         
  613         return (result);
  614 }
  615 
  616 /*
  617  * Get Attributes.
  618  */
  619 static RRIP_TABLE rrip_table_analyze[] = {
  620         { "PX", cd9660_rrip_attr,       cd9660_rrip_defattr,
  621             ISO_SUSP_ATTR },
  622         { "TF", cd9660_rrip_tstamp,     cd9660_rrip_deftstamp,
  623             ISO_SUSP_TSTAMP },
  624         { "PN", cd9660_rrip_device,     0,
  625             ISO_SUSP_DEVICE },
  626         { "RR", cd9660_rrip_idflag,     0,
  627             ISO_SUSP_IDFLAG },
  628         { "CE", cd9660_rrip_cont,       0,
  629             ISO_SUSP_CONT },
  630         { "ST", cd9660_rrip_stop,       0,
  631             ISO_SUSP_STOP },
  632         { "",   0,                      0,
  633             0 }
  634 };
  635 
  636 int
  637 cd9660_rrip_analyze(isodir, inop, imp)
  638         struct iso_directory_record *isodir;
  639         struct iso_node *inop;
  640         struct iso_mnt *imp;
  641 {
  642         ISO_RRIP_ANALYZE analyze;
  643         
  644         analyze.inop = inop;
  645         analyze.imp = imp;
  646         analyze.fields = ISO_SUSP_ATTR | ISO_SUSP_TSTAMP | ISO_SUSP_DEVICE;
  647         
  648         return (cd9660_rrip_loop(isodir, &analyze, rrip_table_analyze));
  649 }
  650 
  651 /* 
  652  * Get Alternate Name.
  653  */
  654 static RRIP_TABLE rrip_table_getname[] = {
  655         { "NM", cd9660_rrip_altname,    cd9660_rrip_defname,
  656             ISO_SUSP_ALTNAME },
  657         { "CL", cd9660_rrip_pclink,     0,
  658             ISO_SUSP_CLINK|ISO_SUSP_PLINK },
  659         { "PL", cd9660_rrip_pclink,     0,
  660             ISO_SUSP_CLINK|ISO_SUSP_PLINK },
  661         { "RE", cd9660_rrip_reldir,     0,
  662             ISO_SUSP_RELDIR },
  663         { "RR", cd9660_rrip_idflag,     0,
  664             ISO_SUSP_IDFLAG },
  665         { "CE", cd9660_rrip_cont,       0,
  666             ISO_SUSP_CONT },
  667         { "ST", cd9660_rrip_stop,       0,
  668             ISO_SUSP_STOP },
  669         { "",   0,                      0,
  670             0 }
  671 };
  672 
  673 int
  674 cd9660_rrip_getname(isodir, outbuf, outlen, inump, imp)
  675         struct iso_directory_record *isodir;
  676         char *outbuf;
  677         u_short *outlen;
  678         ino_t *inump;
  679         struct iso_mnt *imp;
  680 {
  681         ISO_RRIP_ANALYZE analyze;
  682         RRIP_TABLE *tab;
  683         u_char c;
  684         
  685         analyze.outbuf = outbuf;
  686         analyze.outlen = outlen;
  687         analyze.maxlen = NAME_MAX;
  688         analyze.inump = inump;
  689         analyze.imp = imp;
  690         analyze.fields = ISO_SUSP_ALTNAME | ISO_SUSP_RELDIR | ISO_SUSP_CLINK |
  691             ISO_SUSP_PLINK;
  692         *outlen = 0;
  693         
  694         isochar(isodir->name, isodir->name + isonum_711(isodir->name_len),
  695             imp->joliet_level, &c);
  696         tab = rrip_table_getname;
  697         if (c == 0 || c == 1) {
  698                 cd9660_rrip_defname(isodir, &analyze);
  699                 
  700                 analyze.fields &= ~ISO_SUSP_ALTNAME;
  701                 tab++;
  702         }
  703         
  704         return (cd9660_rrip_loop(isodir, &analyze, tab));
  705 }
  706 
  707 /* 
  708  * Get Symbolic Link.
  709  */
  710 static RRIP_TABLE rrip_table_getsymname[] = {
  711         { "SL", cd9660_rrip_slink,      0,      ISO_SUSP_SLINK },
  712         { "RR", cd9660_rrip_idflag,     0,      ISO_SUSP_IDFLAG },
  713         { "CE", cd9660_rrip_cont,       0,      ISO_SUSP_CONT },
  714         { "ST", cd9660_rrip_stop,       0,      ISO_SUSP_STOP },
  715         { "",   0,                      0,      0 }
  716 };
  717 
  718 int
  719 cd9660_rrip_getsymname(isodir, outbuf, outlen, imp)
  720         struct iso_directory_record *isodir;
  721         char *outbuf;
  722         u_short *outlen;
  723         struct iso_mnt *imp;
  724 {
  725         ISO_RRIP_ANALYZE analyze;
  726         
  727         analyze.outbuf = outbuf;
  728         analyze.outlen = outlen;
  729         *outlen = 0;
  730         analyze.maxlen = MAXPATHLEN;
  731         analyze.cont = 1;               /* don't start with a slash */
  732         analyze.imp = imp;
  733         analyze.fields = ISO_SUSP_SLINK;
  734         
  735         return (cd9660_rrip_loop(isodir, &analyze, rrip_table_getsymname) &
  736             ISO_SUSP_SLINK);
  737 }
  738 
  739 static RRIP_TABLE rrip_table_extref[] = {
  740         { "ER", cd9660_rrip_extref,     0,      ISO_SUSP_EXTREF },
  741         { "CE", cd9660_rrip_cont,       0,      ISO_SUSP_CONT },
  742         { "ST", cd9660_rrip_stop,       0,      ISO_SUSP_STOP },
  743         { "",   0,                      0,      0 }
  744 };
  745 
  746 /*
  747  * Check for Rock Ridge Extension and return offset of its fields.
  748  * Note: We insist on the ER field.
  749  */
  750 int
  751 cd9660_rrip_offset(isodir, imp)
  752         struct iso_directory_record *isodir;
  753         struct iso_mnt *imp;
  754 {
  755         ISO_RRIP_OFFSET *p;
  756         ISO_RRIP_ANALYZE analyze;
  757         
  758         imp->rr_skip0 = 0;
  759         p = (ISO_RRIP_OFFSET *)(isodir->name + 1);
  760         if (bcmp(p, "SP\7\1\276\357", 6)) {
  761                 /* Maybe, it's a CDROM XA disc? */
  762                 imp->rr_skip0 = 15;
  763                 p = (ISO_RRIP_OFFSET *)((char *)p + 15);
  764                 if (bcmp(p, "SP\7\1\276\357", 6))
  765                         return (-1);
  766         }
  767         
  768         analyze.imp = imp;
  769         analyze.fields = ISO_SUSP_EXTREF;
  770         if (!(cd9660_rrip_loop(isodir, &analyze, rrip_table_extref) &
  771             ISO_SUSP_EXTREF))
  772                 return (-1);
  773         
  774         return (isonum_711(p->skip));
  775 }

/* [<][>][^][v][top][bottom][index][help] */