diff options
Diffstat (limited to 'src/cmd/9660/jchar.c')
-rw-r--r-- | src/cmd/9660/jchar.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/cmd/9660/jchar.c b/src/cmd/9660/jchar.c new file mode 100644 index 00000000..c49da635 --- /dev/null +++ b/src/cmd/9660/jchar.c @@ -0,0 +1,138 @@ +#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; + strtorune(r, s); + for(p=r; *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); +} + |