xref: /plan9-contrib/sys/src/cmd/disk/9660/ichar.c (revision 5d459b5a09e427ae1acd4e6afcf028853c73946e)
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 #include <ctype.h>
680ee5cbfSDavid du Colombier 
780ee5cbfSDavid du Colombier #include "iso9660.h"
880ee5cbfSDavid du Colombier 
980ee5cbfSDavid du Colombier /*
1080ee5cbfSDavid du Colombier  * ISO 9660 file names must be uppercase, digits, or underscore.
1180ee5cbfSDavid du Colombier  * We use lowercase, digits, and underscore, translating lower to upper
1280ee5cbfSDavid du Colombier  * in mkisostring, and upper to lower in isostring.
1380ee5cbfSDavid du Colombier  * Files with uppercase letters in their names are thus nonconforming.
1480ee5cbfSDavid du Colombier  * Conforming files also must have a basename
1580ee5cbfSDavid du Colombier  * at most 8 letters and at most one suffix of at most 3 letters.
1680ee5cbfSDavid du Colombier  */
1780ee5cbfSDavid du Colombier char*
isostring(uchar * buf,int len)1880ee5cbfSDavid du Colombier isostring(uchar *buf, int len)
1980ee5cbfSDavid du Colombier {
2080ee5cbfSDavid du Colombier 	char *p, *q;
2180ee5cbfSDavid du Colombier 
2280ee5cbfSDavid du Colombier 	p = emalloc(len+1);
2380ee5cbfSDavid du Colombier 	memmove(p, buf, len);
2480ee5cbfSDavid du Colombier 	p[len] = '\0';
2580ee5cbfSDavid du Colombier 	while(len > 0 && p[len-1] == ' ')
2680ee5cbfSDavid du Colombier 		p[--len] = '\0';
2780ee5cbfSDavid du Colombier 	for(q=p; *q; q++)
2880ee5cbfSDavid du Colombier 		*q = tolower(*q);
2980ee5cbfSDavid du Colombier 
3080ee5cbfSDavid du Colombier 	q = atom(p);
3180ee5cbfSDavid du Colombier 	free(p);
3280ee5cbfSDavid du Colombier 	return q;
3380ee5cbfSDavid du Colombier }
3480ee5cbfSDavid du Colombier 
3580ee5cbfSDavid du Colombier int
isisofrog(char c)3680ee5cbfSDavid du Colombier isisofrog(char c)
3780ee5cbfSDavid du Colombier {
3880ee5cbfSDavid du Colombier 	if(c >= '0' && c <= '9')
3980ee5cbfSDavid du Colombier 		return 0;
4080ee5cbfSDavid du Colombier 	if(c >= 'a' && c <= 'z')
4180ee5cbfSDavid du Colombier 		return 0;
4280ee5cbfSDavid du Colombier 	if(c == '_')
4380ee5cbfSDavid du Colombier 		return 0;
4480ee5cbfSDavid du Colombier 
4580ee5cbfSDavid du Colombier 	return 1;
4680ee5cbfSDavid du Colombier }
4780ee5cbfSDavid du Colombier 
4880ee5cbfSDavid du Colombier int
isbadiso9660(char * s)4980ee5cbfSDavid du Colombier isbadiso9660(char *s)
5080ee5cbfSDavid du Colombier {
5180ee5cbfSDavid du Colombier 	char *p, *q;
5280ee5cbfSDavid du Colombier 	int i;
5380ee5cbfSDavid du Colombier 
5480ee5cbfSDavid du Colombier 	if((p = strchr(s, '.')) != nil) {
5580ee5cbfSDavid du Colombier 		if(p-s > 8)
5680ee5cbfSDavid du Colombier 			return 1;
5780ee5cbfSDavid du Colombier 		for(q=s; q<p; q++)
5880ee5cbfSDavid du Colombier 			if(isisofrog(*q))
5980ee5cbfSDavid du Colombier 				return 1;
6080ee5cbfSDavid du Colombier 		if(strlen(p+1) > 3)
6180ee5cbfSDavid du Colombier 			return 1;
6280ee5cbfSDavid du Colombier 		for(q=p+1; *q; q++)
6380ee5cbfSDavid du Colombier 			if(isisofrog(*q))
6480ee5cbfSDavid du Colombier 				return 1;
6580ee5cbfSDavid du Colombier 	} else {
6680ee5cbfSDavid du Colombier 		if(strlen(s) > 8)
6780ee5cbfSDavid du Colombier 			return 1;
6880ee5cbfSDavid du Colombier 		for(q=s; *q; q++)
6980ee5cbfSDavid du Colombier 			if(isisofrog(*q))
7080ee5cbfSDavid du Colombier 				return 1;
7180ee5cbfSDavid du Colombier 
7280ee5cbfSDavid du Colombier 		/*
7380ee5cbfSDavid du Colombier 		 * we rename files of the form [FD]dddddd
7480ee5cbfSDavid du Colombier 		 * so they don't interfere with us.
7580ee5cbfSDavid du Colombier 		 */
7680ee5cbfSDavid du Colombier 		if(strlen(s) == 7 && (s[0] == 'D' || s[0] == 'F')) {
7780ee5cbfSDavid du Colombier 			for(i=1; i<7; i++)
7880ee5cbfSDavid du Colombier 				if(s[i] < '0' || s[i] > '9')
7980ee5cbfSDavid du Colombier 					break;
8080ee5cbfSDavid du Colombier 			if(i == 7)
8180ee5cbfSDavid du Colombier 				return 1;
8280ee5cbfSDavid du Colombier 		}
8380ee5cbfSDavid du Colombier 	}
8480ee5cbfSDavid du Colombier 	return 0;
8580ee5cbfSDavid du Colombier }
8680ee5cbfSDavid du Colombier 
8780ee5cbfSDavid du Colombier /*
8880ee5cbfSDavid du Colombier  * ISO9660 name comparison
8980ee5cbfSDavid du Colombier  *
9080ee5cbfSDavid du Colombier  * The standard algorithm is as follows:
9180ee5cbfSDavid du Colombier  *   Take the filenames without extensions, pad the shorter with 0x20s (spaces),
9280ee5cbfSDavid du Colombier  *   and do strcmp.  If they are equal, go on.
9380ee5cbfSDavid du Colombier  *   Take the extensions, pad the shorter with 0x20s (spaces),
9480ee5cbfSDavid du Colombier  *   and do strcmp.  If they are equal, go on.
9580ee5cbfSDavid du Colombier  *   Compare the version numbers.
9680ee5cbfSDavid du Colombier  *
9780ee5cbfSDavid du Colombier  * Since Plan 9 names are not allowed to contain characters 0x00-0x1F,
9880ee5cbfSDavid du Colombier  * the padded comparisons are equivalent to using strcmp directly.
9980ee5cbfSDavid du Colombier  * We still need to handle the base and extension differently,
10080ee5cbfSDavid du Colombier  * so that .foo sorts before !foo.foo.
10180ee5cbfSDavid du Colombier  */
10280ee5cbfSDavid du Colombier int
isocmp(const void * va,const void * vb)10380ee5cbfSDavid du Colombier isocmp(const void *va, const void *vb)
10480ee5cbfSDavid du Colombier {
10580ee5cbfSDavid du Colombier 	int i;
1069a747e4fSDavid du Colombier 	char s1[32], s2[32], *b1, *b2, *e1, *e2;
10780ee5cbfSDavid du Colombier 	const Direc *a, *b;
10880ee5cbfSDavid du Colombier 
10980ee5cbfSDavid du Colombier 	a = va;
11080ee5cbfSDavid du Colombier 	b = vb;
11180ee5cbfSDavid du Colombier 
112*5d459b5aSDavid du Colombier 	strecpy(s1, s1+sizeof s1, a->confname);
113*5d459b5aSDavid du Colombier 	b1 = s1;
114*5d459b5aSDavid du Colombier 	strecpy(s2, s2+sizeof s2, b->confname);
115*5d459b5aSDavid du Colombier 	b2 = s2;
11680ee5cbfSDavid du Colombier 	if((e1 = strchr(b1, '.')) != nil)
11780ee5cbfSDavid du Colombier 		*e1++ = '\0';
11880ee5cbfSDavid du Colombier 	else
11980ee5cbfSDavid du Colombier 		e1 = "";
12080ee5cbfSDavid du Colombier 	if((e2 = strchr(b2, '.')) != nil)
12180ee5cbfSDavid du Colombier 		*e2++ = '\0';
12280ee5cbfSDavid du Colombier 	else
12380ee5cbfSDavid du Colombier 		e2 = "";
12480ee5cbfSDavid du Colombier 
12580ee5cbfSDavid du Colombier 	if((i = strcmp(b1, b2)) != 0)
12680ee5cbfSDavid du Colombier 		return i;
12780ee5cbfSDavid du Colombier 
12880ee5cbfSDavid du Colombier 	return strcmp(e1, e2);
12980ee5cbfSDavid du Colombier }
13080ee5cbfSDavid du Colombier 
13180ee5cbfSDavid du Colombier static char*
mkisostring(char * isobuf,int n,char * s)13280ee5cbfSDavid du Colombier mkisostring(char *isobuf, int n, char *s)
13380ee5cbfSDavid du Colombier {
13480ee5cbfSDavid du Colombier 	char *p, *q, *eq;
13580ee5cbfSDavid du Colombier 
13680ee5cbfSDavid du Colombier 	eq = isobuf+n;
13780ee5cbfSDavid du Colombier 	for(p=s, q=isobuf; *p && q < eq; p++)
13880ee5cbfSDavid du Colombier 		if('a' <= *p && *p <= 'z')
13980ee5cbfSDavid du Colombier 			*q++ = *p+'A'-'a';
140b7b24591SDavid du Colombier 		else
141b7b24591SDavid du Colombier 			*q++ = *p;
14280ee5cbfSDavid du Colombier 
14380ee5cbfSDavid du Colombier 	while(q < eq)
14480ee5cbfSDavid du Colombier 		*q++ = ' ';
14580ee5cbfSDavid du Colombier 
14680ee5cbfSDavid du Colombier 	return isobuf;
14780ee5cbfSDavid du Colombier }
14880ee5cbfSDavid du Colombier 
14980ee5cbfSDavid du Colombier void
Cputisopvd(Cdimg * cd,Cdinfo info)15080ee5cbfSDavid du Colombier Cputisopvd(Cdimg *cd, Cdinfo info)
15180ee5cbfSDavid du Colombier {
15280ee5cbfSDavid du Colombier 	char buf[130];
15380ee5cbfSDavid du Colombier 
15480ee5cbfSDavid du Colombier 	Cputc(cd, 1);				/* primary volume descriptor */
15580ee5cbfSDavid du Colombier 	Cputs(cd, "CD001", 5);			/* standard identifier */
15680ee5cbfSDavid du Colombier 	Cputc(cd, 1);				/* volume descriptor version */
15780ee5cbfSDavid du Colombier 	Cputc(cd, 0);				/* unused */
15880ee5cbfSDavid du Colombier 
15980ee5cbfSDavid du Colombier 	assert(~info.flags & (CDplan9|CDrockridge));
16080ee5cbfSDavid du Colombier 
16180ee5cbfSDavid du Colombier 	/* system identifier */
16280ee5cbfSDavid du Colombier 	strcpy(buf, "");
16380ee5cbfSDavid du Colombier 	if(info.flags & CDplan9)
16480ee5cbfSDavid du Colombier 		strcat(buf, "plan 9 ");
16580ee5cbfSDavid du Colombier 	if(info.flags & CDrockridge)
16680ee5cbfSDavid du Colombier 		strcat(buf, "rrip ");
1679a747e4fSDavid du Colombier 	if(info.flags & CDbootable)
1689a747e4fSDavid du Colombier 		strcat(buf, "boot ");
16980ee5cbfSDavid du Colombier 	if(info.flags & CDconform)
17080ee5cbfSDavid du Colombier 		strcat(buf, "iso9660");
17180ee5cbfSDavid du Colombier 	else
17280ee5cbfSDavid du Colombier 		strcat(buf, "utf8");
17380ee5cbfSDavid du Colombier 
17480ee5cbfSDavid du Colombier 	struprcpy(buf, buf);
17580ee5cbfSDavid du Colombier 	Cputs(cd, buf, 32);
17680ee5cbfSDavid du Colombier 
17780ee5cbfSDavid du Colombier 	Cputs(cd, mkisostring(buf, 32, info.volumename), 32);			/* volume identifier */
17880ee5cbfSDavid du Colombier 
17980ee5cbfSDavid du Colombier 	Crepeat(cd, 0, 8);				/* unused */
18080ee5cbfSDavid du Colombier 	Cputn(cd, 0, 4);				/* volume space size */
18180ee5cbfSDavid du Colombier 	Crepeat(cd, 0, 32);				/* unused */
18280ee5cbfSDavid du Colombier 	Cputn(cd, 1, 2);				/* volume set size */
18380ee5cbfSDavid du Colombier 	Cputn(cd, 1, 2);				/* volume sequence number */
18480ee5cbfSDavid du Colombier 	Cputn(cd, Blocksize, 2);			/* logical block size */
18580ee5cbfSDavid du Colombier 	Cputn(cd, 0, 4);				/* path table size */
18680ee5cbfSDavid du Colombier 	Cputnl(cd, 0, 4);				/* location of Lpath */
18780ee5cbfSDavid du Colombier 	Cputnl(cd, 0, 4);				/* location of optional Lpath */
18880ee5cbfSDavid du Colombier 	Cputnm(cd, 0, 4);				/* location of Mpath */
18980ee5cbfSDavid du Colombier 	Cputnm(cd, 0, 4);				/* location of optional Mpath */
19080ee5cbfSDavid du Colombier 	Cputisodir(cd, nil, DTroot, 1, Cwoffset(cd));			/* root directory */
19180ee5cbfSDavid du Colombier 
19280ee5cbfSDavid du Colombier 	Cputs(cd, mkisostring(buf, 128, info.volumeset), 128);		/* volume set identifier */
19380ee5cbfSDavid du Colombier 	Cputs(cd, mkisostring(buf, 128, info.publisher), 128);			/* publisher identifier */
19480ee5cbfSDavid du Colombier 	Cputs(cd, mkisostring(buf, 128, info.preparer), 128);			/* data preparer identifier */
19580ee5cbfSDavid du Colombier 	Cputs(cd, mkisostring(buf, 128, info.application), 128);		/* application identifier */
19680ee5cbfSDavid du Colombier 
19780ee5cbfSDavid du Colombier 	Cputs(cd, "", 37);			/* copyright notice */
19880ee5cbfSDavid du Colombier 	Cputs(cd, "", 37);			/* abstract */
19980ee5cbfSDavid du Colombier 	Cputs(cd, "", 37);			/* bibliographic file */
20080ee5cbfSDavid du Colombier 	Cputdate1(cd, now);				/* volume creation date */
20180ee5cbfSDavid du Colombier 	Cputdate1(cd, now);				/* volume modification date */
20280ee5cbfSDavid du Colombier 	Cputdate1(cd, 0);				/* volume expiration date */
20380ee5cbfSDavid du Colombier 	Cputdate1(cd, 0);				/* volume effective date */
20480ee5cbfSDavid du Colombier 	Cputc(cd, 1);				/* file structure version */
20580ee5cbfSDavid du Colombier 	Cpadblock(cd);
20680ee5cbfSDavid du Colombier }
207