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                 if (!cont) {
  139                         if (len < ana->maxlen) {
  140                                 len++;
  141                                 *outbuf++ = '/';
  142                         }
  143                 }
  144                 cont = 0;
  145 
  146                 inbuf = "..";
  147                 wlen = 0;
  148 
  149                 switch (*pcomp->cflag) {
  150                 case ISO_SUSP_CFLAG_CURRENT:
  151                         /* Inserting Current */
  152                         wlen = 1;
  153                         break;
  154 
  155                 case ISO_SUSP_CFLAG_PARENT:
  156                         /* Inserting Parent */
  157                         wlen = 2;
  158                         break;
  159 
  160                 case ISO_SUSP_CFLAG_ROOT:
  161                         /* Inserting slash for ROOT */
  162                         /* Double slash, nothing really to do here. */
  163                         break;
  164 
  165                 case ISO_SUSP_CFLAG_VOLROOT:
  166                         /* Inserting a mount point i.e. "/cdrom" */
  167                         /* same as above */
  168                         outbuf -= len;
  169                         len = 0;
  170                         inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname;
  171                         wlen = strlen(inbuf);
  172                         break;
  173 
  174                 case ISO_SUSP_CFLAG_HOST:
  175                         /* Inserting hostname i.e. "kurt.tools.de" */
  176                         getcredhostname(curthread->td_ucred, hostbuf,
  177                             sizeof(hostbuf));
  178                         inbuf = hostbuf;
  179                         wlen = strlen(inbuf);
  180                         break;
  181 
  182                 case ISO_SUSP_CFLAG_CONTINUE:
  183                         cont = 1;
  184                         /* FALLTHROUGH */
  185                 case 0:
  186                         /* Inserting component */
  187                         wlen = isonum_711(pcomp->clen);
  188                         inbuf = pcomp->name;
  189                         break;
  190                 default:
  191                         printf("RRIP with incorrect flags?");
  192                         wlen = ana->maxlen + 1;
  193                         break;
  194                 }
  195 
  196                 if (len + wlen > ana->maxlen) {
  197                         /* indicate error to caller */
  198                         ana->cont = 1;
  199                         ana->fields = 0;
  200                         ana->outbuf -= *ana->outlen;
  201                         *ana->outlen = 0;
  202                         return 0;
  203                 }
  204 
  205                 memcpy(outbuf, inbuf, wlen);
  206                 outbuf += wlen;
  207                 len += wlen;
  208         }
  209         ana->outbuf = outbuf;
  210         *ana->outlen = len;
  211         ana->cont = cont;
  212 
  213         if (!isonum_711(p->flags)) {
  214                 ana->fields &= ~ISO_SUSP_SLINK;
  215                 return ISO_SUSP_SLINK;
  216         }
  217         return 0;
  218 }
  219 
  220 /*
  221  * Alternate name
  222  */
  223 static int
  224 cd9660_rrip_altname(p,ana)
  225         ISO_RRIP_ALTNAME *p;
  226         ISO_RRIP_ANALYZE *ana;
  227 {
  228         char *inbuf;
  229         int wlen;
  230         int cont;
  231         char hostbuf[MAXHOSTNAMELEN];
  232 
  233         inbuf = "..";
  234         wlen = 0;
  235         cont = 0;
  236 
  237         switch (*p->flags) {
  238         case ISO_SUSP_CFLAG_CURRENT:
  239                 /* Inserting Current */
  240                 wlen = 1;
  241                 break;
  242 
  243         case ISO_SUSP_CFLAG_PARENT:
  244                 /* Inserting Parent */
  245                 wlen = 2;
  246                 break;
  247 
  248         case ISO_SUSP_CFLAG_HOST:
  249                 /* Inserting hostname i.e. "kurt.tools.de" */
  250                 getcredhostname(curthread->td_ucred, hostbuf, sizeof(hostbuf));
  251                 inbuf = hostbuf;
  252                 wlen = strlen(inbuf);
  253                 break;
  254 
  255         case ISO_SUSP_CFLAG_CONTINUE:
  256                 cont = 1;
  257                 /* FALLTHROUGH */
  258         case 0:
  259                 /* Inserting component */
  260                 wlen = isonum_711(p->h.length) - 5;
  261                 inbuf = (char *)p + 5;
  262                 break;
  263 
  264         default:
  265                 printf("RRIP with incorrect NM flags?\n");
  266                 wlen = ana->maxlen + 1;
  267                 break;
  268         }
  269 
  270         if ((*ana->outlen += wlen) > ana->maxlen) {
  271                 /* treat as no name field */
  272                 ana->fields &= ~ISO_SUSP_ALTNAME;
  273                 ana->outbuf -= *ana->outlen - wlen;
  274                 *ana->outlen = 0;
  275                 return 0;
  276         }
  277 
  278         memcpy(ana->outbuf, inbuf, wlen);
  279         ana->outbuf += wlen;
  280 
  281         if (!cont) {
  282                 ana->fields &= ~ISO_SUSP_ALTNAME;
  283                 return ISO_SUSP_ALTNAME;
  284         }
  285         return 0;
  286 }
  287 
  288 static void
  289 cd9660_rrip_defname(isodir,ana)
  290         struct iso_directory_record *isodir;
  291         ISO_RRIP_ANALYZE *ana;
  292 {
  293         isofntrans(isodir->name,isonum_711(isodir->name_len),
  294                    ana->outbuf,ana->outlen,
  295                    1,isonum_711(isodir->flags)&4, ana->imp->joliet_level,
  296                    ana->imp->im_flags, ana->imp->im_d2l);
  297         switch (*ana->outbuf) {
  298         default:
  299                 break;
  300         case 1:
  301                 *ana->outlen = 2;
  302                 /* FALLTHROUGH */
  303         case 0:
  304                 /* outlen is 1 already */
  305                 strcpy(ana->outbuf,"..");
  306                 break;
  307         }
  308 }
  309 
  310 /*
  311  * Parent or Child Link
  312  */
  313 static int
  314 cd9660_rrip_pclink(p,ana)
  315         ISO_RRIP_CLINK  *p;
  316         ISO_RRIP_ANALYZE *ana;
  317 {
  318         *ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift;
  319         ana->fields &= ~(ISO_SUSP_CLINK|ISO_SUSP_PLINK);
  320         return *p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK;
  321 }
  322 
  323 /*
  324  * Relocated directory
  325  */
  326 static int
  327 cd9660_rrip_reldir(p,ana)
  328         ISO_RRIP_RELDIR  *p;
  329         ISO_RRIP_ANALYZE *ana;
  330 {
  331         /* special hack to make caller aware of RE field */
  332         *ana->outlen = 0;
  333         ana->fields = 0;
  334         return ISO_SUSP_RELDIR|ISO_SUSP_ALTNAME|ISO_SUSP_CLINK|ISO_SUSP_PLINK;
  335 }
  336 
  337 static int
  338 cd9660_rrip_tstamp(p,ana)
  339         ISO_RRIP_TSTAMP *p;
  340         ISO_RRIP_ANALYZE *ana;
  341 {
  342         u_char *ptime;
  343 
  344         ptime = p->time;
  345 
  346         /* Check a format of time stamp (7bytes/17bytes) */
  347         if (!(*p->flags&ISO_SUSP_TSTAMP_FORM17)) {
  348                 if (*p->flags&ISO_SUSP_TSTAMP_CREAT)
  349                         ptime += 7;
  350 
  351                 if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) {
  352                         cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_mtime,
  353                                             ISO_FTYPE_RRIP);
  354                         ptime += 7;
  355                 } else
  356                         memset(&ana->inop->inode.iso_mtime, 0, sizeof(struct timespec));
  357 
  358                 if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) {
  359                         cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_atime,
  360                                             ISO_FTYPE_RRIP);
  361                         ptime += 7;
  362                 } else
  363                         ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime;
  364 
  365                 if (*p->flags&ISO_SUSP_TSTAMP_ATTR)
  366                         cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_ctime,
  367                                             ISO_FTYPE_RRIP);
  368                 else
  369                         ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime;
  370 
  371         } else {
  372                 if (*p->flags&ISO_SUSP_TSTAMP_CREAT)
  373                         ptime += 17;
  374 
  375                 if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) {
  376                         cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_mtime);
  377                         ptime += 17;
  378                 } else
  379                         memset(&ana->inop->inode.iso_mtime, 0, sizeof(struct timespec));
  380 
  381                 if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) {
  382                         cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_atime);
  383                         ptime += 17;
  384                 } else
  385                         ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime;
  386 
  387                 if (*p->flags&ISO_SUSP_TSTAMP_ATTR)
  388                         cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_ctime);
  389                 else
  390                         ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime;
  391         }
  392         ana->fields &= ~ISO_SUSP_TSTAMP;
  393         return ISO_SUSP_TSTAMP;
  394 }
  395 
  396 static void
  397 cd9660_rrip_deftstamp(isodir,ana)
  398         struct iso_directory_record  *isodir;
  399         ISO_RRIP_ANALYZE *ana;
  400 {
  401         cd9660_deftstamp(isodir,ana->inop,NULL,ISO_FTYPE_RRIP);
  402 }
  403 
  404 /*
  405  * POSIX device modes
  406  */
  407 static int
  408 cd9660_rrip_device(p,ana)
  409         ISO_RRIP_DEVICE *p;
  410         ISO_RRIP_ANALYZE *ana;
  411 {
  412         u_int high, low;
  413 
  414         high = isonum_733(p->dev_t_high);
  415         low  = isonum_733(p->dev_t_low);
  416 
  417         if (high == 0)
  418                 ana->inop->inode.iso_rdev = makedev(major(low), minor(low));
  419         else
  420                 ana->inop->inode.iso_rdev = makedev(high, minor(low));
  421         ana->fields &= ~ISO_SUSP_DEVICE;
  422         return ISO_SUSP_DEVICE;
  423 }
  424 
  425 /*
  426  * Flag indicating
  427  */
  428 static int
  429 cd9660_rrip_idflag(p,ana)
  430         ISO_RRIP_IDFLAG *p;
  431         ISO_RRIP_ANALYZE *ana;
  432 {
  433         ana->fields &= isonum_711(p->flags)|~0xff; /* don't touch high bits */
  434         /* special handling of RE field */
  435         if (ana->fields&ISO_SUSP_RELDIR)
  436                 return cd9660_rrip_reldir(/* XXX */ (ISO_RRIP_RELDIR *)p,ana);
  437 
  438         return ISO_SUSP_IDFLAG;
  439 }
  440 
  441 /*
  442  * Continuation pointer
  443  */
  444 static int
  445 cd9660_rrip_cont(p,ana)
  446         ISO_RRIP_CONT *p;
  447         ISO_RRIP_ANALYZE *ana;
  448 {
  449         ana->iso_ce_blk = isonum_733(p->location);
  450         ana->iso_ce_off = isonum_733(p->offset);
  451         ana->iso_ce_len = isonum_733(p->length);
  452         return ISO_SUSP_CONT;
  453 }
  454 
  455 /*
  456  * System Use end
  457  */
  458 static int
  459 cd9660_rrip_stop(p,ana)
  460         ISO_SUSP_HEADER *p;
  461         ISO_RRIP_ANALYZE *ana;
  462 {
  463         return ISO_SUSP_STOP;
  464 }
  465 
  466 /*
  467  * Extension reference
  468  */
  469 static int
  470 cd9660_rrip_extref(p,ana)
  471         ISO_RRIP_EXTREF *p;
  472         ISO_RRIP_ANALYZE *ana;
  473 {
  474         if ( ! ((isonum_711(p->len_id) == 10
  475               && bcmp((char *)p + 8,"RRIP_1991A",10) == 0)
  476             || (isonum_711(p->len_id) == 10
  477               && bcmp((char *)p + 8,"IEEE_P1282",10) == 0)
  478             || (isonum_711(p->len_id) ==  9
  479               && bcmp((char *)p + 8,"IEEE_1282",  9) == 0))
  480             || isonum_711(p->version) != 1)
  481                 return 0;
  482         ana->fields &= ~ISO_SUSP_EXTREF;
  483         return ISO_SUSP_EXTREF;
  484 }
  485 
  486 static int
  487 cd9660_rrip_loop(isodir,ana,table)
  488         struct iso_directory_record *isodir;
  489         ISO_RRIP_ANALYZE *ana;
  490         RRIP_TABLE *table;
  491 {
  492         RRIP_TABLE *ptable;
  493         ISO_SUSP_HEADER *phead;
  494         ISO_SUSP_HEADER *pend;
  495         struct buf *bp = NULL;
  496         char *pwhead;
  497         u_short c;
  498         int result;
  499 
  500         /*
  501          * Note: If name length is odd,
  502          *       it will be padding 1 byte after the name
  503          */
  504         pwhead = isodir->name + isonum_711(isodir->name_len);
  505         if (!(isonum_711(isodir->name_len)&1))
  506                 pwhead++;
  507         isochar(isodir->name, pwhead, ana->imp->joliet_level, &c, NULL,
  508                 ana->imp->im_flags, ana->imp->im_d2l);
  509 
  510         /* If it's not the '.' entry of the root dir obey SP field */
  511         if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent)
  512                 pwhead += ana->imp->rr_skip;
  513         else
  514                 pwhead += ana->imp->rr_skip0;
  515 
  516         phead = (ISO_SUSP_HEADER *)pwhead;
  517         pend = (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length));
  518 
  519         result = 0;
  520         while (1) {
  521                 ana->iso_ce_len = 0;
  522                 /*
  523                  * Note: "pend" should be more than one SUSP header
  524                  */
  525                 while (pend >= phead + 1) {
  526                         if (isonum_711(phead->version) == 1) {
  527                                 for (ptable = table; ptable->func; ptable++) {
  528                                         if (*phead->type == *ptable->type
  529                                             && phead->type[1] == ptable->type[1]) {
  530                                                 result |= ptable->func(phead,ana);
  531                                                 break;
  532                                         }
  533                                 }
  534                                 if (!ana->fields)
  535                                         break;
  536                         }
  537                         if (result&ISO_SUSP_STOP) {
  538                                 result &= ~ISO_SUSP_STOP;
  539                                 break;
  540                         }
  541                         /* plausibility check */
  542                         if (isonum_711(phead->length) < sizeof(*phead))
  543                                 break;
  544                         /*
  545                          * move to next SUSP
  546                          * Hopefully this works with newer versions, too
  547                          */
  548                         phead = (ISO_SUSP_HEADER *)((char *)phead + isonum_711(phead->length));
  549                 }
  550 
  551                 if (ana->fields && ana->iso_ce_len) {
  552                         if (ana->iso_ce_blk >= ana->imp->volume_space_size
  553                             || ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size
  554                             || bread(ana->imp->im_devvp,
  555                                      ana->iso_ce_blk <<
  556                                      (ana->imp->im_bshift - DEV_BSHIFT),
  557                                      ana->imp->logical_block_size, NOCRED, &bp))
  558                                 /* what to do now? */
  559                                 break;
  560                         phead = (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off);
  561                         pend = (ISO_SUSP_HEADER *) ((char *)phead + ana->iso_ce_len);
  562                 } else
  563                         break;
  564         }
  565         if (bp)
  566                 brelse(bp);
  567         /*
  568          * If we don't find the Basic SUSP stuffs, just set default value
  569          *   (attribute/time stamp)
  570          */
  571         for (ptable = table; ptable->func2; ptable++)
  572                 if (!(ptable->result&result))
  573                         ptable->func2(isodir,ana);
  574 
  575         return result;
  576 }
  577 
  578 /*
  579  * Get Attributes.
  580  */
  581 /*
  582  * XXX the casts are bogus but will do for now.
  583  */
  584 #define BC      (rrt_func_t *)
  585 static RRIP_TABLE rrip_table_analyze[] = {
  586         { "PX", BC cd9660_rrip_attr,    cd9660_rrip_defattr,    ISO_SUSP_ATTR },
  587         { "TF", BC cd9660_rrip_tstamp,  cd9660_rrip_deftstamp,  ISO_SUSP_TSTAMP },
  588         { "PN", BC cd9660_rrip_device,  0,                      ISO_SUSP_DEVICE },
  589         { "RR", BC cd9660_rrip_idflag,  0,                      ISO_SUSP_IDFLAG },
  590         { "CE", BC cd9660_rrip_cont,    0,                      ISO_SUSP_CONT },
  591         { "ST", BC cd9660_rrip_stop,    0,                      ISO_SUSP_STOP },
  592         { "",   0,                      0,                      0 }
  593 };
  594 
  595 int
  596 cd9660_rrip_analyze(isodir,inop,imp)
  597         struct iso_directory_record *isodir;
  598         struct iso_node *inop;
  599         struct iso_mnt *imp;
  600 {
  601         ISO_RRIP_ANALYZE analyze;
  602 
  603         analyze.inop = inop;
  604         analyze.imp = imp;
  605         analyze.fields = ISO_SUSP_ATTR|ISO_SUSP_TSTAMP|ISO_SUSP_DEVICE;
  606 
  607         return cd9660_rrip_loop(isodir,&analyze,rrip_table_analyze);
  608 }
  609 
  610 /*
  611  * Get Alternate Name.
  612  */
  613 static RRIP_TABLE rrip_table_getname[] = {
  614         { "NM", BC cd9660_rrip_altname, cd9660_rrip_defname,    ISO_SUSP_ALTNAME },
  615         { "CL", BC cd9660_rrip_pclink,  0,                      ISO_SUSP_CLINK|ISO_SUSP_PLINK },
  616         { "PL", BC cd9660_rrip_pclink,  0,                      ISO_SUSP_CLINK|ISO_SUSP_PLINK },
  617         { "RE", BC cd9660_rrip_reldir,  0,                      ISO_SUSP_RELDIR },
  618         { "RR", BC cd9660_rrip_idflag,  0,                      ISO_SUSP_IDFLAG },
  619         { "CE", BC cd9660_rrip_cont,    0,                      ISO_SUSP_CONT },
  620         { "ST", BC cd9660_rrip_stop,    0,                      ISO_SUSP_STOP },
  621         { "",   0,                      0,                      0 }
  622 };
  623 
  624 int
  625 cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp)
  626         struct iso_directory_record *isodir;
  627         char *outbuf;
  628         u_short *outlen;
  629         cd_ino_t *inump;
  630         struct iso_mnt *imp;
  631 {
  632         ISO_RRIP_ANALYZE analyze;
  633         RRIP_TABLE *tab;
  634         u_short c;
  635 
  636         analyze.outbuf = outbuf;
  637         analyze.outlen = outlen;
  638         analyze.maxlen = NAME_MAX;
  639         analyze.inump = inump;
  640         analyze.imp = imp;
  641         analyze.fields = ISO_SUSP_ALTNAME|ISO_SUSP_RELDIR|ISO_SUSP_CLINK|ISO_SUSP_PLINK;
  642         *outlen = 0;
  643 
  644         isochar(isodir->name, isodir->name + isonum_711(isodir->name_len),
  645                 imp->joliet_level, &c, NULL, imp->im_flags, imp->im_d2l);
  646         tab = rrip_table_getname;
  647         if (c == 0 || c == 1) {
  648                 cd9660_rrip_defname(isodir,&analyze);
  649 
  650                 analyze.fields &= ~ISO_SUSP_ALTNAME;
  651                 tab++;
  652         }
  653 
  654         return cd9660_rrip_loop(isodir,&analyze,tab);
  655 }
  656 
  657 /*
  658  * Get Symbolic Link.
  659  */
  660 static RRIP_TABLE rrip_table_getsymname[] = {
  661         { "SL", BC cd9660_rrip_slink,   0,                      ISO_SUSP_SLINK },
  662         { "RR", BC cd9660_rrip_idflag,  0,                      ISO_SUSP_IDFLAG },
  663         { "CE", BC cd9660_rrip_cont,    0,                      ISO_SUSP_CONT },
  664         { "ST", BC cd9660_rrip_stop,    0,                      ISO_SUSP_STOP },
  665         { "",   0,                      0,                      0 }
  666 };
  667 
  668 int
  669 cd9660_rrip_getsymname(isodir,outbuf,outlen,imp)
  670         struct iso_directory_record *isodir;
  671         char *outbuf;
  672         u_short *outlen;
  673         struct iso_mnt *imp;
  674 {
  675         ISO_RRIP_ANALYZE analyze;
  676 
  677         analyze.outbuf = outbuf;
  678         analyze.outlen = outlen;
  679         *outlen = 0;
  680         analyze.maxlen = MAXPATHLEN;
  681         analyze.cont = 1;               /* don't start with a slash */
  682         analyze.imp = imp;
  683         analyze.fields = ISO_SUSP_SLINK;
  684 
  685         return (cd9660_rrip_loop(isodir,&analyze,rrip_table_getsymname)&ISO_SUSP_SLINK);
  686 }
  687 
  688 static RRIP_TABLE rrip_table_extref[] = {
  689         { "ER", BC cd9660_rrip_extref,  0,                      ISO_SUSP_EXTREF },
  690         { "CE", BC cd9660_rrip_cont,    0,                      ISO_SUSP_CONT },
  691         { "ST", BC cd9660_rrip_stop,    0,                      ISO_SUSP_STOP },
  692         { "",   0,                      0,                      0 }
  693 };
  694 
  695 /*
  696  * Check for Rock Ridge Extension and return offset of its fields.
  697  * Note: We insist on the ER field.
  698  */
  699 int
  700 cd9660_rrip_offset(isodir,imp)
  701         struct iso_directory_record *isodir;
  702         struct iso_mnt *imp;
  703 {
  704         ISO_RRIP_OFFSET *p;
  705         ISO_RRIP_ANALYZE analyze;
  706 
  707         imp->rr_skip0 = 0;
  708         p = (ISO_RRIP_OFFSET *)(isodir->name + 1);
  709         if (bcmp(p,"SP\7\1\276\357",6)) {
  710                 /* Maybe, it's a CDROM XA disc? */
  711                 imp->rr_skip0 = 15;
  712                 p = (ISO_RRIP_OFFSET *)((char *)p + 15);
  713                 if (bcmp(p,"SP\7\1\276\357",6))
  714                         return -1;
  715         }
  716 
  717         analyze.imp = imp;
  718         analyze.fields = ISO_SUSP_EXTREF;
  719         if (!(cd9660_rrip_loop(isodir,&analyze,rrip_table_extref)&ISO_SUSP_EXTREF))
  720                 return -1;
  721 
  722         return isonum_711(p->skip);
  723 }

Cache object: 63e31f2c92cc036e96f6923aa5c7c9d6


[ 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.