jchar.c (3331B)
1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <libsec.h> 5 6 #include "iso9660.h" 7 8 char* 9 jolietstring(uchar *buf, int len) 10 { 11 char *p, *q; 12 int i; 13 Rune *rp; 14 15 rp = emalloc(sizeof(Rune)*(len/2+1)); 16 p = emalloc(UTFmax*(len/2+1)); 17 18 for(i=0; i<len/2; i++) 19 rp[i] = (buf[2*i]<<8) | buf[2*i+1]; 20 rp[i] = (Rune)'\0'; 21 22 snprint(p, UTFmax*(len/2+1), "%S", rp); 23 q = atom(p); 24 free(p); 25 return q; 26 } 27 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 } 40 41 int 42 isbadjoliet(char *s) 43 { 44 Rune r[256], *p; 45 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 } 54 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 */ 64 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; 72 73 a = va; 74 b = vb; 75 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; 82 83 if((e2 = runechr(b2, (Rune)'.')) != nil) 84 *e2++ = '\0'; 85 else 86 e2 = emptystring; 87 88 if((i = runecmp(b1, b2)) != 0) 89 return i; 90 91 return runecmp(e1, e2); 92 } 93 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 */ 104 105 Cputrscvt(cd, "Joliet Plan 9", 32); /* system identifier */ 106 Cputrscvt(cd, info.volumename, 32); /* volume identifier */ 107 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); 113 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); 137 }