Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <libsec.h>
6 #include "iso9660.h"
8 char*
9 jolietstring(uchar *buf, int len)
10 {
11 char *p, *q;
12 int i;
13 Rune *rp;
15 rp = emalloc(sizeof(Rune)*(len/2+1));
16 p = emalloc(UTFmax*(len/2+1));
18 for(i=0; i<len/2; i++)
19 rp[i] = (buf[2*i]<<8) | buf[2*i+1];
20 rp[i] = (Rune)'\0';
22 snprint(p, UTFmax*(len/2+1), "%S", rp);
23 q = atom(p);
24 free(p);
25 return q;
26 }
28 /*
29 * Joliet name validity check
30 *
31 * Joliet names have length at most 128 bytes (64 runes),
32 * and cannot contain '*', '/', ':', ';', '?', or '\'.
33 */
34 int
35 isjolietfrog(Rune r)
36 {
37 return r=='*' || r=='/' || r==':'
38 || r==';' || r=='?' || r=='\\';
39 }
41 int
42 isbadjoliet(char *s)
43 {
44 Rune r[256], *p;
46 if(utflen(s) > 64)
47 return 1;
48 strtorune(r, s);
49 for(p=r; *p; p++)
50 if(isjolietfrog(*p))
51 return 1;
52 return 0;
53 }
55 /*
56 * Joliet name comparison
57 *
58 * The standard algorithm is the ISO9660 algorithm but
59 * on the encoded Runes. Runes are encoded in big endian
60 * format, so we can just use runecmp.
61 *
62 * Padding is with zeros, but that still doesn't affect us.
63 */
65 static Rune emptystring[] = { (Rune)0 };
66 int
67 jolietcmp(const void *va, const void *vb)
68 {
69 int i;
70 Rune s1[256], s2[256], *b1, *b2, *e1, *e2; /*BUG*/
71 const Direc *a, *b;
73 a = va;
74 b = vb;
76 b1 = strtorune(s1, a->confname);
77 b2 = strtorune(s2, b->confname);
78 if((e1 = runechr(b1, (Rune)'.')) != nil)
79 *e1++ = '\0';
80 else
81 e1 = emptystring;
83 if((e2 = runechr(b2, (Rune)'.')) != nil)
84 *e2++ = '\0';
85 else
86 e2 = emptystring;
88 if((i = runecmp(b1, b2)) != 0)
89 return i;
91 return runecmp(e1, e2);
92 }
94 /*
95 * Write a Joliet secondary volume descriptor.
96 */
97 void
98 Cputjolietsvd(Cdimg *cd, Cdinfo info)
99 {
100 Cputc(cd, 2); /* secondary volume descriptor */
101 Cputs(cd, "CD001", 5); /* standard identifier */
102 Cputc(cd, 1); /* volume descriptor version */
103 Cputc(cd, 0); /* unused */
105 Cputrscvt(cd, "Joliet Plan 9", 32); /* system identifier */
106 Cputrscvt(cd, info.volumename, 32); /* volume identifier */
108 Crepeat(cd, 0, 8); /* unused */
109 Cputn(cd, 0, 4); /* volume space size */
110 Cputc(cd, 0x25); /* escape sequences: UCS-2 Level 2 */
111 Cputc(cd, 0x2F);
112 Cputc(cd, 0x43);
114 Crepeat(cd, 0, 29);
115 Cputn(cd, 1, 2); /* volume set size */
116 Cputn(cd, 1, 2); /* volume sequence number */
117 Cputn(cd, Blocksize, 2); /* logical block size */
118 Cputn(cd, 0, 4); /* path table size */
119 Cputnl(cd, 0, 4); /* location of Lpath */
120 Cputnl(cd, 0, 4); /* location of optional Lpath */
121 Cputnm(cd, 0, 4); /* location of Mpath */
122 Cputnm(cd, 0, 4); /* location of optional Mpath */
123 Cputjolietdir(cd, nil, DTroot, 1, Cwoffset(cd)); /* root directory */
124 Cputrscvt(cd, info.volumeset, 128); /* volume set identifier */
125 Cputrscvt(cd, info.publisher, 128); /* publisher identifier */
126 Cputrscvt(cd, info.preparer, 128); /* data preparer identifier */
127 Cputrscvt(cd, info.application, 128); /* application identifier */
128 Cputrscvt(cd, "", 37); /* copyright notice */
129 Cputrscvt(cd, "", 37); /* abstract */
130 Cputrscvt(cd, "", 37); /* bibliographic file */
131 Cputdate1(cd, now); /* volume creation date */
132 Cputdate1(cd, now); /* volume modification date */
133 Cputdate1(cd, 0); /* volume expiration date */
134 Cputdate1(cd, 0); /* volume effective date */
135 Cputc(cd, 1); /* file structure version */
136 Cpadblock(cd);