ref: d39d1a5303541539f61488317b220c1eb724d7d3
dir: /sys/src/cmd/disk/9660/jchar.c/
#include <u.h> #include <libc.h> #include <bio.h> #include <libsec.h> #include "iso9660.h" char* jolietstring(uchar *buf, int len) { char *p, *q; int i; Rune *rp; rp = emalloc(sizeof(Rune)*(len/2+1)); p = emalloc(UTFmax*(len/2+1)); for(i=0; i<len/2; i++) rp[i] = (buf[2*i]<<8) | buf[2*i+1]; rp[i] = (Rune)'\0'; snprint(p, UTFmax*(len/2+1), "%S", rp); q = atom(p); free(p); return q; } /* * Joliet name validity check * * Joliet names have length at most 128 bytes (64 runes), * and cannot contain '*', '/', ':', ';', '?', or '\'. */ int isjolietfrog(Rune r) { return r==L'*' || r==L'/' || r==L':' || r==';' || r=='?' || r=='\\'; } int isbadjoliet(char *s) { Rune r[256], *p; if(utflen(s) > 64) return 1; for(p=strtorune(r, s); *p; p++) if(isjolietfrog(*p)) return 1; return 0; } /* * Joliet name comparison * * The standard algorithm is the ISO9660 algorithm but * on the encoded Runes. Runes are encoded in big endian * format, so we can just use runecmp. * * Padding is with zeros, but that still doesn't affect us. */ static Rune emptystring[] = { (Rune)0 }; int jolietcmp(const void *va, const void *vb) { int i; Rune s1[256], s2[256], *b1, *b2, *e1, *e2; /*BUG*/ const Direc *a, *b; a = va; b = vb; b1 = strtorune(s1, a->confname); b2 = strtorune(s2, b->confname); if((e1 = runechr(b1, (Rune)'.')) != nil) *e1++ = '\0'; else e1 = emptystring; if((e2 = runechr(b2, (Rune)'.')) != nil) *e2++ = '\0'; else e2 = emptystring; if((i = runecmp(b1, b2)) != 0) return i; return runecmp(e1, e2); } /* * Write a Joliet secondary volume descriptor. */ void Cputjolietsvd(Cdimg *cd, Cdinfo info) { Cputc(cd, 2); /* secondary volume descriptor */ Cputs(cd, "CD001", 5); /* standard identifier */ Cputc(cd, 1); /* volume descriptor version */ Cputc(cd, 0); /* unused */ Cputrscvt(cd, "Joliet Plan 9", 32); /* system identifier */ Cputrscvt(cd, info.volumename, 32); /* volume identifier */ Crepeat(cd, 0, 8); /* unused */ Cputn(cd, 0, 4); /* volume space size */ Cputc(cd, 0x25); /* escape sequences: UCS-2 Level 2 */ Cputc(cd, 0x2F); Cputc(cd, 0x43); Crepeat(cd, 0, 29); Cputn(cd, 1, 2); /* volume set size */ Cputn(cd, 1, 2); /* volume sequence number */ Cputn(cd, Blocksize, 2); /* logical block size */ Cputn(cd, 0, 4); /* path table size */ Cputnl(cd, 0, 4); /* location of Lpath */ Cputnl(cd, 0, 4); /* location of optional Lpath */ Cputnm(cd, 0, 4); /* location of Mpath */ Cputnm(cd, 0, 4); /* location of optional Mpath */ Cputjolietdir(cd, nil, DTroot, 1, Cwoffset(cd)); /* root directory */ Cputrscvt(cd, info.volumeset, 128); /* volume set identifier */ Cputrscvt(cd, info.publisher, 128); /* publisher identifier */ Cputrscvt(cd, info.preparer, 128); /* data preparer identifier */ Cputrscvt(cd, info.application, 128); /* application identifier */ Cputrscvt(cd, "", 37); /* copyright notice */ Cputrscvt(cd, "", 37); /* abstract */ Cputrscvt(cd, "", 37); /* bibliographic file */ Cputdate1(cd, now); /* volume creation date */ Cputdate1(cd, now); /* volume modification date */ Cputdate1(cd, 0); /* volume expiration date */ Cputdate1(cd, 0); /* volume effective date */ Cputc(cd, 1); /* file structure version */ Cpadblock(cd); }