The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/cd9660/cd9660_rrip.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: bbe98a4938fdae58851a88fd659cbe93


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.