Blame


1 7285a491 2004-06-17 devnull #include <u.h>
2 7285a491 2004-06-17 devnull #include <libc.h>
3 7285a491 2004-06-17 devnull #include <bio.h>
4 7285a491 2004-06-17 devnull #include <libsec.h>
5 7285a491 2004-06-17 devnull #include <ctype.h>
6 7285a491 2004-06-17 devnull
7 7285a491 2004-06-17 devnull #include "iso9660.h"
8 7285a491 2004-06-17 devnull
9 7285a491 2004-06-17 devnull /*
10 7285a491 2004-06-17 devnull * ISO 9660 file names must be uppercase, digits, or underscore.
11 7285a491 2004-06-17 devnull * We use lowercase, digits, and underscore, translating lower to upper
12 7285a491 2004-06-17 devnull * in mkisostring, and upper to lower in isostring.
13 7285a491 2004-06-17 devnull * Files with uppercase letters in their names are thus nonconforming.
14 7285a491 2004-06-17 devnull * Conforming files also must have a basename
15 7285a491 2004-06-17 devnull * at most 8 letters and at most one suffix of at most 3 letters.
16 7285a491 2004-06-17 devnull */
17 7285a491 2004-06-17 devnull char*
18 7285a491 2004-06-17 devnull isostring(uchar *buf, int len)
19 7285a491 2004-06-17 devnull {
20 7285a491 2004-06-17 devnull char *p, *q;
21 7285a491 2004-06-17 devnull
22 7285a491 2004-06-17 devnull p = emalloc(len+1);
23 7285a491 2004-06-17 devnull memmove(p, buf, len);
24 7285a491 2004-06-17 devnull p[len] = '\0';
25 7285a491 2004-06-17 devnull while(len > 0 && p[len-1] == ' ')
26 7285a491 2004-06-17 devnull p[--len] = '\0';
27 7285a491 2004-06-17 devnull for(q=p; *q; q++)
28 3bd56b04 2005-09-09 devnull *q = tolower((uchar)*q);
29 7285a491 2004-06-17 devnull q = atom(p);
30 7285a491 2004-06-17 devnull free(p);
31 7285a491 2004-06-17 devnull return q;
32 7285a491 2004-06-17 devnull }
33 7285a491 2004-06-17 devnull
34 7285a491 2004-06-17 devnull int
35 7285a491 2004-06-17 devnull isisofrog(char c)
36 7285a491 2004-06-17 devnull {
37 7285a491 2004-06-17 devnull if(c >= '0' && c <= '9')
38 7285a491 2004-06-17 devnull return 0;
39 7285a491 2004-06-17 devnull if(c >= 'a' && c <= 'z')
40 7285a491 2004-06-17 devnull return 0;
41 7285a491 2004-06-17 devnull if(c == '_')
42 7285a491 2004-06-17 devnull return 0;
43 7285a491 2004-06-17 devnull
44 7285a491 2004-06-17 devnull return 1;
45 7285a491 2004-06-17 devnull }
46 7285a491 2004-06-17 devnull
47 7285a491 2004-06-17 devnull int
48 7285a491 2004-06-17 devnull isbadiso9660(char *s)
49 7285a491 2004-06-17 devnull {
50 7285a491 2004-06-17 devnull char *p, *q;
51 7285a491 2004-06-17 devnull int i;
52 7285a491 2004-06-17 devnull
53 7285a491 2004-06-17 devnull if((p = strchr(s, '.')) != nil) {
54 7285a491 2004-06-17 devnull if(p-s > 8)
55 7285a491 2004-06-17 devnull return 1;
56 7285a491 2004-06-17 devnull for(q=s; q<p; q++)
57 7285a491 2004-06-17 devnull if(isisofrog(*q))
58 7285a491 2004-06-17 devnull return 1;
59 7285a491 2004-06-17 devnull if(strlen(p+1) > 3)
60 7285a491 2004-06-17 devnull return 1;
61 7285a491 2004-06-17 devnull for(q=p+1; *q; q++)
62 7285a491 2004-06-17 devnull if(isisofrog(*q))
63 7285a491 2004-06-17 devnull return 1;
64 7285a491 2004-06-17 devnull } else {
65 7285a491 2004-06-17 devnull if(strlen(s) > 8)
66 7285a491 2004-06-17 devnull return 1;
67 7285a491 2004-06-17 devnull for(q=s; *q; q++)
68 7285a491 2004-06-17 devnull if(isisofrog(*q))
69 7285a491 2004-06-17 devnull return 1;
70 7285a491 2004-06-17 devnull
71 7285a491 2004-06-17 devnull /*
72 7285a491 2004-06-17 devnull * we rename files of the form [FD]dddddd
73 7285a491 2004-06-17 devnull * so they don't interfere with us.
74 7285a491 2004-06-17 devnull */
75 7285a491 2004-06-17 devnull if(strlen(s) == 7 && (s[0] == 'D' || s[0] == 'F')) {
76 7285a491 2004-06-17 devnull for(i=1; i<7; i++)
77 7285a491 2004-06-17 devnull if(s[i] < '0' || s[i] > '9')
78 7285a491 2004-06-17 devnull break;
79 7285a491 2004-06-17 devnull if(i == 7)
80 7285a491 2004-06-17 devnull return 1;
81 7285a491 2004-06-17 devnull }
82 7285a491 2004-06-17 devnull }
83 7285a491 2004-06-17 devnull return 0;
84 7285a491 2004-06-17 devnull }
85 7285a491 2004-06-17 devnull
86 7285a491 2004-06-17 devnull /*
87 7285a491 2004-06-17 devnull * ISO9660 name comparison
88 7285a491 2004-06-17 devnull *
89 7285a491 2004-06-17 devnull * The standard algorithm is as follows:
90 7285a491 2004-06-17 devnull * Take the filenames without extensions, pad the shorter with 0x20s (spaces),
91 7285a491 2004-06-17 devnull * and do strcmp. If they are equal, go on.
92 7285a491 2004-06-17 devnull * Take the extensions, pad the shorter with 0x20s (spaces),
93 7285a491 2004-06-17 devnull * and do strcmp. If they are equal, go on.
94 7285a491 2004-06-17 devnull * Compare the version numbers.
95 7285a491 2004-06-17 devnull *
96 7285a491 2004-06-17 devnull * Since Plan 9 names are not allowed to contain characters 0x00-0x1F,
97 7285a491 2004-06-17 devnull * the padded comparisons are equivalent to using strcmp directly.
98 7285a491 2004-06-17 devnull * We still need to handle the base and extension differently,
99 7285a491 2004-06-17 devnull * so that .foo sorts before !foo.foo.
100 7285a491 2004-06-17 devnull */
101 7285a491 2004-06-17 devnull int
102 7285a491 2004-06-17 devnull isocmp(const void *va, const void *vb)
103 7285a491 2004-06-17 devnull {
104 7285a491 2004-06-17 devnull int i;
105 7285a491 2004-06-17 devnull char s1[32], s2[32], *b1, *b2, *e1, *e2;
106 7285a491 2004-06-17 devnull const Direc *a, *b;
107 7285a491 2004-06-17 devnull
108 7285a491 2004-06-17 devnull a = va;
109 7285a491 2004-06-17 devnull b = vb;
110 7285a491 2004-06-17 devnull
111 7285a491 2004-06-17 devnull strecpy(s1, s1+sizeof s1, a->confname);
112 7285a491 2004-06-17 devnull b1 = s1;
113 7285a491 2004-06-17 devnull strecpy(s2, s2+sizeof s2, b->confname);
114 7285a491 2004-06-17 devnull b2 = s2;
115 7285a491 2004-06-17 devnull if((e1 = strchr(b1, '.')) != nil)
116 7285a491 2004-06-17 devnull *e1++ = '\0';
117 7285a491 2004-06-17 devnull else
118 7285a491 2004-06-17 devnull e1 = "";
119 7285a491 2004-06-17 devnull if((e2 = strchr(b2, '.')) != nil)
120 7285a491 2004-06-17 devnull *e2++ = '\0';
121 7285a491 2004-06-17 devnull else
122 7285a491 2004-06-17 devnull e2 = "";
123 7285a491 2004-06-17 devnull
124 7285a491 2004-06-17 devnull if((i = strcmp(b1, b2)) != 0)
125 7285a491 2004-06-17 devnull return i;
126 7285a491 2004-06-17 devnull
127 7285a491 2004-06-17 devnull return strcmp(e1, e2);
128 7285a491 2004-06-17 devnull }
129 7285a491 2004-06-17 devnull
130 7285a491 2004-06-17 devnull static char*
131 7285a491 2004-06-17 devnull mkisostring(char *isobuf, int n, char *s)
132 7285a491 2004-06-17 devnull {
133 7285a491 2004-06-17 devnull char *p, *q, *eq;
134 7285a491 2004-06-17 devnull
135 7285a491 2004-06-17 devnull eq = isobuf+n;
136 7285a491 2004-06-17 devnull for(p=s, q=isobuf; *p && q < eq; p++)
137 7285a491 2004-06-17 devnull if('a' <= *p && *p <= 'z')
138 7285a491 2004-06-17 devnull *q++ = *p+'A'-'a';
139 7285a491 2004-06-17 devnull else
140 7285a491 2004-06-17 devnull *q++ = *p;
141 7285a491 2004-06-17 devnull
142 7285a491 2004-06-17 devnull while(q < eq)
143 7285a491 2004-06-17 devnull *q++ = ' ';
144 7285a491 2004-06-17 devnull
145 7285a491 2004-06-17 devnull return isobuf;
146 7285a491 2004-06-17 devnull }
147 7285a491 2004-06-17 devnull
148 7285a491 2004-06-17 devnull void
149 7285a491 2004-06-17 devnull Cputisopvd(Cdimg *cd, Cdinfo info)
150 7285a491 2004-06-17 devnull {
151 7285a491 2004-06-17 devnull char buf[130];
152 7285a491 2004-06-17 devnull
153 7285a491 2004-06-17 devnull Cputc(cd, 1); /* primary volume descriptor */
154 7285a491 2004-06-17 devnull Cputs(cd, "CD001", 5); /* standard identifier */
155 7285a491 2004-06-17 devnull Cputc(cd, 1); /* volume descriptor version */
156 7285a491 2004-06-17 devnull Cputc(cd, 0); /* unused */
157 7285a491 2004-06-17 devnull
158 7285a491 2004-06-17 devnull assert(~info.flags & (CDplan9|CDrockridge));
159 7285a491 2004-06-17 devnull
160 7285a491 2004-06-17 devnull /* system identifier */
161 7285a491 2004-06-17 devnull strcpy(buf, "");
162 7285a491 2004-06-17 devnull if(info.flags & CDplan9)
163 7285a491 2004-06-17 devnull strcat(buf, "plan 9 ");
164 7285a491 2004-06-17 devnull if(info.flags & CDrockridge)
165 7285a491 2004-06-17 devnull strcat(buf, "rrip ");
166 7285a491 2004-06-17 devnull if(info.flags & CDbootable)
167 7285a491 2004-06-17 devnull strcat(buf, "boot ");
168 7285a491 2004-06-17 devnull if(info.flags & CDconform)
169 7285a491 2004-06-17 devnull strcat(buf, "iso9660");
170 7285a491 2004-06-17 devnull else
171 7285a491 2004-06-17 devnull strcat(buf, "utf8");
172 7285a491 2004-06-17 devnull
173 7285a491 2004-06-17 devnull struprcpy(buf, buf);
174 7285a491 2004-06-17 devnull Cputs(cd, buf, 32);
175 7285a491 2004-06-17 devnull
176 7285a491 2004-06-17 devnull Cputs(cd, mkisostring(buf, 32, info.volumename), 32); /* volume identifier */
177 7285a491 2004-06-17 devnull
178 7285a491 2004-06-17 devnull Crepeat(cd, 0, 8); /* unused */
179 7285a491 2004-06-17 devnull Cputn(cd, 0, 4); /* volume space size */
180 7285a491 2004-06-17 devnull Crepeat(cd, 0, 32); /* unused */
181 7285a491 2004-06-17 devnull Cputn(cd, 1, 2); /* volume set size */
182 7285a491 2004-06-17 devnull Cputn(cd, 1, 2); /* volume sequence number */
183 7285a491 2004-06-17 devnull Cputn(cd, Blocksize, 2); /* logical block size */
184 7285a491 2004-06-17 devnull Cputn(cd, 0, 4); /* path table size */
185 7285a491 2004-06-17 devnull Cputnl(cd, 0, 4); /* location of Lpath */
186 7285a491 2004-06-17 devnull Cputnl(cd, 0, 4); /* location of optional Lpath */
187 7285a491 2004-06-17 devnull Cputnm(cd, 0, 4); /* location of Mpath */
188 7285a491 2004-06-17 devnull Cputnm(cd, 0, 4); /* location of optional Mpath */
189 7285a491 2004-06-17 devnull Cputisodir(cd, nil, DTroot, 1, Cwoffset(cd)); /* root directory */
190 7285a491 2004-06-17 devnull
191 7285a491 2004-06-17 devnull Cputs(cd, mkisostring(buf, 128, info.volumeset), 128); /* volume set identifier */
192 7285a491 2004-06-17 devnull Cputs(cd, mkisostring(buf, 128, info.publisher), 128); /* publisher identifier */
193 7285a491 2004-06-17 devnull Cputs(cd, mkisostring(buf, 128, info.preparer), 128); /* data preparer identifier */
194 7285a491 2004-06-17 devnull Cputs(cd, mkisostring(buf, 128, info.application), 128); /* application identifier */
195 7285a491 2004-06-17 devnull
196 7285a491 2004-06-17 devnull Cputs(cd, "", 37); /* copyright notice */
197 7285a491 2004-06-17 devnull Cputs(cd, "", 37); /* abstract */
198 7285a491 2004-06-17 devnull Cputs(cd, "", 37); /* bibliographic file */
199 7285a491 2004-06-17 devnull Cputdate1(cd, now); /* volume creation date */
200 7285a491 2004-06-17 devnull Cputdate1(cd, now); /* volume modification date */
201 7285a491 2004-06-17 devnull Cputdate1(cd, 0); /* volume expiration date */
202 7285a491 2004-06-17 devnull Cputdate1(cd, 0); /* volume effective date */
203 7285a491 2004-06-17 devnull Cputc(cd, 1); /* file structure version */
204 7285a491 2004-06-17 devnull Cpadblock(cd);
205 7285a491 2004-06-17 devnull }