xref: /plan9-contrib/sys/src/cmd/disk/9660/jchar.c (revision d9306527b4a7229dcf0cf3c58aed36bb9da82854)
180ee5cbfSDavid du Colombier #include <u.h>
280ee5cbfSDavid du Colombier #include <libc.h>
380ee5cbfSDavid du Colombier #include <bio.h>
480ee5cbfSDavid du Colombier #include <libsec.h>
580ee5cbfSDavid du Colombier 
680ee5cbfSDavid du Colombier #include "iso9660.h"
780ee5cbfSDavid du Colombier 
880ee5cbfSDavid du Colombier char*
jolietstring(uchar * buf,int len)980ee5cbfSDavid du Colombier jolietstring(uchar *buf, int len)
1080ee5cbfSDavid du Colombier {
1180ee5cbfSDavid du Colombier 	char *p, *q;
1280ee5cbfSDavid du Colombier 	int i;
1380ee5cbfSDavid du Colombier 	Rune *rp;
1480ee5cbfSDavid du Colombier 
1580ee5cbfSDavid du Colombier 	rp = emalloc(sizeof(Rune)*(len/2+1));
1680ee5cbfSDavid du Colombier 	p = emalloc(UTFmax*(len/2+1));
1780ee5cbfSDavid du Colombier 
1880ee5cbfSDavid du Colombier 	for(i=0; i<len/2; i++)
1980ee5cbfSDavid du Colombier 		rp[i] = (buf[2*i]<<8) | buf[2*i+1];
2080ee5cbfSDavid du Colombier 	rp[i] = (Rune)'\0';
2180ee5cbfSDavid du Colombier 
2280ee5cbfSDavid du Colombier 	snprint(p, UTFmax*(len/2+1), "%S", rp);
2380ee5cbfSDavid du Colombier 	q = atom(p);
2480ee5cbfSDavid du Colombier 	free(p);
2580ee5cbfSDavid du Colombier 	return q;
2680ee5cbfSDavid du Colombier }
2780ee5cbfSDavid du Colombier 
2880ee5cbfSDavid du Colombier /*
2980ee5cbfSDavid du Colombier  * Joliet name validity check
3080ee5cbfSDavid du Colombier  *
31*d9306527SDavid du Colombier  * Joliet names have length at most 128 bytes (64 runes),
3280ee5cbfSDavid du Colombier  * and cannot contain '*', '/', ':', ';', '?', or '\'.
3380ee5cbfSDavid du Colombier  */
3480ee5cbfSDavid du Colombier int
isjolietfrog(Rune r)3580ee5cbfSDavid du Colombier isjolietfrog(Rune r)
3680ee5cbfSDavid du Colombier {
3780ee5cbfSDavid du Colombier 	return r==L'*' || r==L'/' || r==L':'
3880ee5cbfSDavid du Colombier 		|| r==';' || r=='?' || r=='\\';
3980ee5cbfSDavid du Colombier }
4080ee5cbfSDavid du Colombier 
4180ee5cbfSDavid du Colombier int
isbadjoliet(char * s)4280ee5cbfSDavid du Colombier isbadjoliet(char *s)
4380ee5cbfSDavid du Colombier {
44*d9306527SDavid du Colombier 	Rune r[256], *p;
4580ee5cbfSDavid du Colombier 
46*d9306527SDavid du Colombier 	if(utflen(s) > 64)
47*d9306527SDavid du Colombier 		return 1;
4880ee5cbfSDavid du Colombier 	strtorune(r, s);
4980ee5cbfSDavid du Colombier 	for(p=r; *p; p++)
5080ee5cbfSDavid du Colombier 		if(isjolietfrog(*p))
5180ee5cbfSDavid du Colombier 			return 1;
5280ee5cbfSDavid du Colombier 	return 0;
5380ee5cbfSDavid du Colombier }
5480ee5cbfSDavid du Colombier 
5580ee5cbfSDavid du Colombier /*
5680ee5cbfSDavid du Colombier  * Joliet name comparison
5780ee5cbfSDavid du Colombier  *
5880ee5cbfSDavid du Colombier  * The standard algorithm is the ISO9660 algorithm but
5980ee5cbfSDavid du Colombier  * on the encoded Runes.  Runes are encoded in big endian
6080ee5cbfSDavid du Colombier  * format, so we can just use runecmp.
6180ee5cbfSDavid du Colombier  *
6280ee5cbfSDavid du Colombier  * Padding is with zeros, but that still doesn't affect us.
6380ee5cbfSDavid du Colombier  */
6480ee5cbfSDavid du Colombier 
6580ee5cbfSDavid du Colombier static Rune emptystring[] = { (Rune)0 };
6680ee5cbfSDavid du Colombier int
jolietcmp(const void * va,const void * vb)6780ee5cbfSDavid du Colombier jolietcmp(const void *va, const void *vb)
6880ee5cbfSDavid du Colombier {
6980ee5cbfSDavid du Colombier 	int i;
709a747e4fSDavid du Colombier 	Rune s1[256], s2[256], *b1, *b2, *e1, *e2;	/*BUG*/
7180ee5cbfSDavid du Colombier 	const Direc *a, *b;
7280ee5cbfSDavid du Colombier 
7380ee5cbfSDavid du Colombier 	a = va;
7480ee5cbfSDavid du Colombier 	b = vb;
7580ee5cbfSDavid du Colombier 
7680ee5cbfSDavid du Colombier 	b1 = strtorune(s1, a->confname);
7780ee5cbfSDavid du Colombier 	b2 = strtorune(s2, b->confname);
7880ee5cbfSDavid du Colombier 	if((e1 = runechr(b1, (Rune)'.')) != nil)
7980ee5cbfSDavid du Colombier 		*e1++ = '\0';
8080ee5cbfSDavid du Colombier 	else
8180ee5cbfSDavid du Colombier 		e1 = emptystring;
8280ee5cbfSDavid du Colombier 
8380ee5cbfSDavid du Colombier 	if((e2 = runechr(b2, (Rune)'.')) != nil)
8480ee5cbfSDavid du Colombier 		*e2++ = '\0';
8580ee5cbfSDavid du Colombier 	else
8680ee5cbfSDavid du Colombier 		e2 = emptystring;
8780ee5cbfSDavid du Colombier 
8880ee5cbfSDavid du Colombier 	if((i = runecmp(b1, b2)) != 0)
8980ee5cbfSDavid du Colombier 		return i;
9080ee5cbfSDavid du Colombier 
9180ee5cbfSDavid du Colombier 	return runecmp(e1, e2);
9280ee5cbfSDavid du Colombier }
9380ee5cbfSDavid du Colombier 
9480ee5cbfSDavid du Colombier /*
9580ee5cbfSDavid du Colombier  * Write a Joliet secondary volume descriptor.
9680ee5cbfSDavid du Colombier  */
9780ee5cbfSDavid du Colombier void
Cputjolietsvd(Cdimg * cd,Cdinfo info)9880ee5cbfSDavid du Colombier Cputjolietsvd(Cdimg *cd, Cdinfo info)
9980ee5cbfSDavid du Colombier {
10080ee5cbfSDavid du Colombier 	Cputc(cd, 2);				/* secondary volume descriptor */
10180ee5cbfSDavid du Colombier 	Cputs(cd, "CD001", 5);			/* standard identifier */
10280ee5cbfSDavid du Colombier 	Cputc(cd, 1);				/* volume descriptor version */
10380ee5cbfSDavid du Colombier 	Cputc(cd, 0);				/* unused */
10480ee5cbfSDavid du Colombier 
10580ee5cbfSDavid du Colombier 	Cputrscvt(cd, "Joliet Plan 9", 32);			/* system identifier */
10680ee5cbfSDavid du Colombier 	Cputrscvt(cd, info.volumename, 32);			/* volume identifier */
10780ee5cbfSDavid du Colombier 
10880ee5cbfSDavid du Colombier 	Crepeat(cd, 0, 8);				/* unused */
10980ee5cbfSDavid du Colombier 	Cputn(cd, 0, 4);				/* volume space size */
11080ee5cbfSDavid du Colombier 	Cputc(cd, 0x25);				/* escape sequences: UCS-2 Level 2 */
11180ee5cbfSDavid du Colombier 	Cputc(cd, 0x2F);
11280ee5cbfSDavid du Colombier 	Cputc(cd, 0x43);
11380ee5cbfSDavid du Colombier 
11480ee5cbfSDavid du Colombier 	Crepeat(cd, 0, 29);
11580ee5cbfSDavid du Colombier 	Cputn(cd, 1, 2);				/* volume set size */
11680ee5cbfSDavid du Colombier 	Cputn(cd, 1, 2);				/* volume sequence number */
11780ee5cbfSDavid du Colombier 	Cputn(cd, Blocksize, 2);			/* logical block size */
11880ee5cbfSDavid du Colombier 	Cputn(cd, 0, 4);				/* path table size */
11980ee5cbfSDavid du Colombier 	Cputnl(cd, 0, 4);				/* location of Lpath */
12080ee5cbfSDavid du Colombier 	Cputnl(cd, 0, 4);				/* location of optional Lpath */
12180ee5cbfSDavid du Colombier 	Cputnm(cd, 0, 4);				/* location of Mpath */
12280ee5cbfSDavid du Colombier 	Cputnm(cd, 0, 4);				/* location of optional Mpath */
12380ee5cbfSDavid du Colombier 	Cputjolietdir(cd, nil, DTroot, 1, Cwoffset(cd));			/* root directory */
12480ee5cbfSDavid du Colombier 	Cputrscvt(cd, info.volumeset, 128);		/* volume set identifier */
12580ee5cbfSDavid du Colombier 	Cputrscvt(cd, info.publisher, 128);			/* publisher identifier */
12680ee5cbfSDavid du Colombier 	Cputrscvt(cd, info.preparer, 128);			/* data preparer identifier */
12780ee5cbfSDavid du Colombier 	Cputrscvt(cd, info.application, 128);		/* application identifier */
12880ee5cbfSDavid du Colombier 	Cputrscvt(cd, "", 37);			/* copyright notice */
12980ee5cbfSDavid du Colombier 	Cputrscvt(cd, "", 37);			/* abstract */
13080ee5cbfSDavid du Colombier 	Cputrscvt(cd, "", 37);			/* bibliographic file */
13180ee5cbfSDavid du Colombier 	Cputdate1(cd, now);				/* volume creation date */
13280ee5cbfSDavid du Colombier 	Cputdate1(cd, now);				/* volume modification date */
13380ee5cbfSDavid du Colombier 	Cputdate1(cd, 0);				/* volume expiration date */
13480ee5cbfSDavid du Colombier 	Cputdate1(cd, 0);				/* volume effective date */
13580ee5cbfSDavid du Colombier 	Cputc(cd, 1);				/* file structure version */
13680ee5cbfSDavid du Colombier 	Cpadblock(cd);
13780ee5cbfSDavid du Colombier }
13880ee5cbfSDavid du Colombier 
139