📄 cd9660_rrip.c
字号:
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 timeval)); 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 voidcd9660_rrip_deftstamp(isodir,ana) struct iso_directory_record *isodir; ISO_RRIP_ANALYZE *ana;{ cd9660_deftstamp(isodir,ana->inop,NULL);}/* * POSIX device modes */static intcd9660_rrip_device(p,ana) ISO_RRIP_DEVICE *p; ISO_RRIP_ANALYZE *ana;{ unsigned high, low; high = isonum_733(p->dev_t_high_l); low = isonum_733(p->dev_t_low_l); 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 intcd9660_rrip_idflag(p,ana) ISO_RRIP_IDFLAG *p; ISO_RRIP_ANALYZE *ana;{ ana->fields &= isonum_711(p->flags)|~0xff; /* don't touch high bits */ /* special handling of RE field */ if (ana->fields&ISO_SUSP_RELDIR) return cd9660_rrip_reldir(p,ana); return ISO_SUSP_IDFLAG;}/* * Continuation pointer */static intcd9660_rrip_cont(p,ana) ISO_RRIP_CONT *p; ISO_RRIP_ANALYZE *ana;{ 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 intcd9660_rrip_stop(p,ana) ISO_SUSP_HEADER *p; ISO_RRIP_ANALYZE *ana;{ /* stop analyzing */ ana->fields = 0; return ISO_SUSP_STOP;}/* * Extension reference */static intcd9660_rrip_extref(p,ana) ISO_RRIP_EXTREF *p; ISO_RRIP_ANALYZE *ana;{ if (isonum_711(p->len_id) != 10 || bcmp((char *)p + 8,"RRIP_1991A",10) || isonum_711(p->version) != 1) return 0; ana->fields &= ~ISO_SUSP_EXTREF; return ISO_SUSP_EXTREF;}typedef struct { char type[2]; int (*func)(); void (*func2)(); int result;} RRIP_TABLE;static intcd9660_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; int i; char *pwhead; int result; /* * Note: If name length is odd, * it will be padding 1 byte after the name */ pwhead = isodir->name + isonum_711(isodir->name_len); if (!(isonum_711(isodir->name_len)&1)) pwhead++; /* If it's not the '.' entry of the root dir obey SP field */ if (*isodir->name != 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; } /* * 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->logical_block_size / DEV_BSIZE, ana->imp->logical_block_size,NOCRED,&bp)) /* what to do now? */ break; phead = (ISO_SUSP_HEADER *)(bp->b_un.b_addr + 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;}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 }};intcd9660_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 from 'AL' record * If either no AL record or 0 length, * it will be return the translated ISO9660 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 }};intcd9660_rrip_getname(isodir,outbuf,outlen,inump,imp) struct iso_directory_record *isodir; char *outbuf; u_short *outlen; ino_t *inump; struct iso_mnt *imp;{ ISO_RRIP_ANALYZE analyze; RRIP_TABLE *tab; 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; tab = rrip_table_getname; if (*isodir->name == 0 || *isodir->name == 1) { cd9660_rrip_defname(isodir,&analyze); analyze.fields &= ~ISO_SUSP_ALTNAME; tab++; } return cd9660_rrip_loop(isodir,&analyze,tab);}/* * Get Symbolic Name from 'SL' record * * Note: isodir should contains SL record! */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 }};intcd9660_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 require the ER field. */intcd9660_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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -