/* * translate and compare a filename * returns (fn - isofn) * Note: Version number plus ';' may be omitted. */ int isofncmp(u_char *fn, int fnlen, u_char *isofn, int isolen, int joliet_level, int flags, void *handle, void *lhandle) { int i, j; u_short c, d; u_char *fnend = fn + fnlen, *isoend = isofn + isolen; for (; fn < fnend; ) { d = sgetrune(fn, fnend - fn, (char const **)&fn, flags, lhandle); if (isofn == isoend) return d; isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle); if (c == ';') { if (d != ';') return d; for (i = 0; fn < fnend; i = i * 10 + *fn++ - '0') { if (*fn < '0' || *fn > '9') { return -1; } } for (j = 0; isofn != isoend; j = j * 10 + c - '0') isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle); return i - j; } if (c != d) { if (c >= 'A' && c <= 'Z') { if (c + ('a' - 'A') != d) { if (d >= 'a' && d <= 'z') return d - ('a' - 'A') - c; else return d - c; } } else return d - c; } } if (isofn != isoend) { isofn += isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle); switch (c) { default: return -c; case '.': if (isofn != isoend) { isochar(isofn, isoend, joliet_level, &c, NULL, flags, handle); if (c == ';') return 0; } return -1; case ';': return 0; } } return 0; }
int cd9660_rrip_getname(struct iso_directory_record *isodir, char *outbuf, u_short *outlen, ino_t *inump, struct iso_mnt *imp) { ISO_RRIP_ANALYZE analyze; RRIP_TABLE *tab; u_short c; analyze.outbuf = outbuf; analyze.outlen = outlen; analyze.maxlen = NAME_MAX; analyze.inump = inump; analyze.imp = imp; analyze.fields = ISO_SUSP_ALTNAME|ISO_SUSP_RELDIR|ISO_SUSP_CLINK|ISO_SUSP_PLINK; *outlen = 0; isochar(isodir->name, isodir->name + isonum_711(isodir->name_len), imp->joliet_level, &c, NULL, imp->im_flags, imp->im_d2l); tab = rrip_table_getname; if (c == 0 || c == 1) { cd9660_rrip_defname(isodir,&analyze); analyze.fields &= ~ISO_SUSP_ALTNAME; tab++; } return cd9660_rrip_loop(isodir,&analyze,tab); }
/* * translate a filename */ void isofntrans(const u_char *infn, int infnlen, u_char *outfn, u_short *outfnlen, int original, int casetrans, int assoc, int joliet_level) { int fnidx = 0; const u_char *infnend = infn + infnlen; u_int16_t c; int sz; if (assoc) { *outfn++ = ASSOCCHAR; fnidx++; } for(; infn != infnend; fnidx += sz) { infn += isochar(infn, infnend, joliet_level, &c); if (casetrans && joliet_level == 0 && c >= 'A' && c <= 'Z') c = c + ('a' - 'A'); else if (!original && c == ';') { if (fnidx > 0 && outfn[-1] == '.') fnidx--; break; } sz = wput(outfn, ISO_MAXNAMLEN - fnidx, c, joliet_level); if (sz == 0) { /* not enough space to write the character */ if (fnidx < ISO_MAXNAMLEN) { *outfn = '?'; fnidx++; } break; } outfn += sz; } *outfnlen = fnidx; }
/* * translate a filename of length > 0 */ void isofntrans(u_char *infn, int infnlen, u_char *outfn, u_short *outfnlen, int original, int assoc, int joliet_level, int flags, void *handle) { u_short c, d = '\0'; u_char *outp = outfn, *infnend = infn + infnlen; int clen; if (assoc) { *outp++ = ASSOCCHAR; } for (; infn != infnend; ) { infn += isochar(infn, infnend, joliet_level, &c, &clen, flags, handle); if (!original && !joliet_level && c >= 'A' && c <= 'Z') c += ('a' - 'A'); else if (!original && c == ';') { outp -= (d == '.'); break; } d = c; while(clen--) *outp++ = c >> (clen << 3); } *outfnlen = outp - outfn; }
static int cd9660_rrip_loop(struct iso_directory_record *isodir, ISO_RRIP_ANALYZE *ana, RRIP_TABLE *table) { RRIP_TABLE *ptable; ISO_SUSP_HEADER *phead; ISO_SUSP_HEADER *pend; struct buf *bp = NULL; char *pwhead; u_short c; 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++; isochar(isodir->name, pwhead, ana->imp->joliet_level, &c, NULL, ana->imp->im_flags, ana->imp->im_d2l); /* If it's not the '.' entry of the root dir obey SP field */ if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent) pwhead += ana->imp->rr_skip; else pwhead += ana->imp->rr_skip0; phead = (ISO_SUSP_HEADER *)pwhead; pend = (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length)); result = 0; while (1) { ana->iso_ce_len = 0; /* * Note: "pend" should be more than one SUSP header */ while (pend >= phead + 1) { if (isonum_711(phead->version) == 1) { for (ptable = table; ptable->func; ptable++) { if (*phead->type == *ptable->type && phead->type[1] == ptable->type[1]) { result |= ptable->func(phead,ana); break; } } if (!ana->fields) break; } if (result&ISO_SUSP_STOP) { result &= ~ISO_SUSP_STOP; break; } /* plausibility check */ if (isonum_711(phead->length) < sizeof(*phead)) break; /* * move to next SUSP * Hopefully this works with newer versions, too */ phead = (ISO_SUSP_HEADER *)((char *)phead + isonum_711(phead->length)); } if (ana->fields && ana->iso_ce_len) { if (ana->iso_ce_blk >= ana->imp->volume_space_size || ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size || bread(ana->imp->im_devvp, lblktooff(ana->imp, ana->iso_ce_blk), ana->imp->logical_block_size, &bp)) /* what to do now? */ break; phead = (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off); pend = (ISO_SUSP_HEADER *) ((char *)phead + ana->iso_ce_len); } else break; } if (bp) brelse(bp); /* * If we don't find the Basic SUSP stuffs, just set default value * (attribute/time stamp) */ for (ptable = table; ptable->func2; ptable++) if (!(ptable->result&result)) ptable->func2(isodir,ana); return result; }
/* * translate and compare a filename * Note: Version number plus ';' may be omitted. */ int isofncmp(const u_char *fn, size_t fnlen, const u_char *isofn, size_t isolen, int joliet_level) { int i, j; u_int16_t fc, ic; const u_char *isoend = isofn + isolen; while (fnlen > 0) { fc = wget(&fn, &fnlen, joliet_level); if (isofn == isoend) return fc; isofn += isochar(isofn, isoend, joliet_level, &ic); if (ic == ';') { switch (fc) { default: return fc; case 0: return 0; case ';': break; } for (i = 0; fnlen-- != 0; i = i * 10 + *fn++ - '0') { if (*fn < '0' || *fn > '9') { return -1; } } for (j = 0; isofn != isoend; j = j * 10 + ic - '0') isofn += isochar(isofn, isoend, joliet_level, &ic); return i - j; } if (ic != fc) { if (ic >= 'A' && ic <= 'Z') { if (ic + ('a' - 'A') != fc) { if (fc >= 'a' && fc <= 'z') fc -= 'a' - 'A'; return (int) fc - (int) ic; } } else return (int) fc - (int) ic; } } if (isofn != isoend) { isofn += isochar(isofn, isoend, joliet_level, &ic); switch (ic) { default: return -1; case '.': if (isofn != isoend) { isochar(isofn, isoend, joliet_level, &ic); if (ic == ';') return 0; } return -1; case ';': return 0; } } return 0; }