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
6 7285a491 2004-06-17 devnull #include "iso9660.h"
7 7285a491 2004-06-17 devnull
8 7285a491 2004-06-17 devnull static int readisodesc(Cdimg*, Voldesc*);
9 7285a491 2004-06-17 devnull static int readjolietdesc(Cdimg*, Voldesc*);
10 7285a491 2004-06-17 devnull
11 7285a491 2004-06-17 devnull /*
12 7285a491 2004-06-17 devnull * It's not strictly conforming; instead it's enough to
13 7285a491 2004-06-17 devnull * get us up and running; presumably the real CD writing
14 7285a491 2004-06-17 devnull * will take care of being conforming.
15 7285a491 2004-06-17 devnull *
16 7285a491 2004-06-17 devnull * Things not conforming include:
17 7285a491 2004-06-17 devnull * - no path table
18 7285a491 2004-06-17 devnull * - root directories are of length zero
19 7285a491 2004-06-17 devnull */
20 7285a491 2004-06-17 devnull Cdimg*
21 7285a491 2004-06-17 devnull createcd(char *file, Cdinfo info)
22 7285a491 2004-06-17 devnull {
23 7285a491 2004-06-17 devnull int fd, xfd;
24 7285a491 2004-06-17 devnull Cdimg *cd;
25 7285a491 2004-06-17 devnull
26 7285a491 2004-06-17 devnull if(access(file, AEXIST) == 0){
27 7285a491 2004-06-17 devnull werrstr("file already exists");
28 7285a491 2004-06-17 devnull return nil;
29 7285a491 2004-06-17 devnull }
30 7285a491 2004-06-17 devnull
31 7285a491 2004-06-17 devnull if((fd = create(file, ORDWR, 0666)) < 0)
32 7285a491 2004-06-17 devnull return nil;
33 7285a491 2004-06-17 devnull
34 7285a491 2004-06-17 devnull cd = emalloc(sizeof *cd);
35 7285a491 2004-06-17 devnull cd->file = atom(file);
36 7285a491 2004-06-17 devnull
37 7285a491 2004-06-17 devnull Binit(&cd->brd, fd, OREAD);
38 7285a491 2004-06-17 devnull
39 7285a491 2004-06-17 devnull if((xfd = open(file, ORDWR)) < 0)
40 7285a491 2004-06-17 devnull sysfatal("can't open file again: %r");
41 7285a491 2004-06-17 devnull Binit(&cd->bwr, xfd, OWRITE);
42 7285a491 2004-06-17 devnull
43 7285a491 2004-06-17 devnull Crepeat(cd, 0, 16*Blocksize);
44 7285a491 2004-06-17 devnull Cputisopvd(cd, info);
45 7285a491 2004-06-17 devnull if(info.flags & CDbootable){
46 7285a491 2004-06-17 devnull cd->bootimage = info.bootimage;
47 7285a491 2004-06-17 devnull cd->flags |= CDbootable;
48 7285a491 2004-06-17 devnull Cputbootvol(cd);
49 7285a491 2004-06-17 devnull }
50 7285a491 2004-06-17 devnull
51 7285a491 2004-06-17 devnull if(readisodesc(cd, &cd->iso) < 0)
52 7285a491 2004-06-17 devnull assert(0);
53 7285a491 2004-06-17 devnull if(info.flags & CDplan9)
54 7285a491 2004-06-17 devnull cd->flags |= CDplan9;
55 7285a491 2004-06-17 devnull else if(info.flags & CDrockridge)
56 7285a491 2004-06-17 devnull cd->flags |= CDrockridge;
57 7285a491 2004-06-17 devnull if(info.flags & CDjoliet) {
58 7285a491 2004-06-17 devnull Cputjolietsvd(cd, info);
59 7285a491 2004-06-17 devnull if(readjolietdesc(cd, &cd->joliet) < 0)
60 7285a491 2004-06-17 devnull assert(0);
61 7285a491 2004-06-17 devnull cd->flags |= CDjoliet;
62 7285a491 2004-06-17 devnull }
63 7285a491 2004-06-17 devnull Cputendvd(cd);
64 7285a491 2004-06-17 devnull
65 7285a491 2004-06-17 devnull if(info.flags & CDdump){
66 7285a491 2004-06-17 devnull cd->nulldump = Cputdumpblock(cd);
67 7285a491 2004-06-17 devnull cd->flags |= CDdump;
68 7285a491 2004-06-17 devnull }
69 7285a491 2004-06-17 devnull if(cd->flags & CDbootable){
70 7285a491 2004-06-17 devnull Cputbootcat(cd);
71 7285a491 2004-06-17 devnull Cupdatebootvol(cd);
72 7285a491 2004-06-17 devnull }
73 7285a491 2004-06-17 devnull
74 7285a491 2004-06-17 devnull if(info.flags & CDconform)
75 7285a491 2004-06-17 devnull cd->flags |= CDconform;
76 7285a491 2004-06-17 devnull
77 7285a491 2004-06-17 devnull cd->flags |= CDnew;
78 7285a491 2004-06-17 devnull cd->nextblock = Cwoffset(cd) / Blocksize;
79 7285a491 2004-06-17 devnull assert(cd->nextblock != 0);
80 7285a491 2004-06-17 devnull
81 7285a491 2004-06-17 devnull return cd;
82 7285a491 2004-06-17 devnull }
83 7285a491 2004-06-17 devnull
84 7285a491 2004-06-17 devnull Cdimg*
85 7285a491 2004-06-17 devnull opencd(char *file, Cdinfo info)
86 7285a491 2004-06-17 devnull {
87 7285a491 2004-06-17 devnull int fd, xfd;
88 7285a491 2004-06-17 devnull Cdimg *cd;
89 7285a491 2004-06-17 devnull Dir *d;
90 7285a491 2004-06-17 devnull
91 7285a491 2004-06-17 devnull if((fd = open(file, ORDWR)) < 0) {
92 7285a491 2004-06-17 devnull if(access(file, AEXIST) == 0)
93 7285a491 2004-06-17 devnull return nil;
94 7285a491 2004-06-17 devnull return createcd(file, info);
95 7285a491 2004-06-17 devnull }
96 7285a491 2004-06-17 devnull
97 7285a491 2004-06-17 devnull if((d = dirfstat(fd)) == nil) {
98 7285a491 2004-06-17 devnull close(fd);
99 7285a491 2004-06-17 devnull return nil;
100 7285a491 2004-06-17 devnull }
101 7285a491 2004-06-17 devnull if(d->length == 0 || d->length % Blocksize) {
102 7285a491 2004-06-17 devnull werrstr("bad length %lld", d->length);
103 7285a491 2004-06-17 devnull close(fd);
104 7285a491 2004-06-17 devnull free(d);
105 7285a491 2004-06-17 devnull return nil;
106 7285a491 2004-06-17 devnull }
107 7285a491 2004-06-17 devnull
108 7285a491 2004-06-17 devnull cd = emalloc(sizeof *cd);
109 7285a491 2004-06-17 devnull cd->file = atom(file);
110 7285a491 2004-06-17 devnull cd->nextblock = d->length / Blocksize;
111 7285a491 2004-06-17 devnull assert(cd->nextblock != 0);
112 7285a491 2004-06-17 devnull free(d);
113 7285a491 2004-06-17 devnull
114 7285a491 2004-06-17 devnull Binit(&cd->brd, fd, OREAD);
115 7285a491 2004-06-17 devnull
116 7285a491 2004-06-17 devnull if((xfd = open(file, ORDWR)) < 0)
117 7285a491 2004-06-17 devnull sysfatal("can't open file again: %r");
118 7285a491 2004-06-17 devnull Binit(&cd->bwr, xfd, OWRITE);
119 7285a491 2004-06-17 devnull
120 7285a491 2004-06-17 devnull if(readisodesc(cd, &cd->iso) < 0) {
121 7285a491 2004-06-17 devnull free(cd);
122 7285a491 2004-06-17 devnull close(fd);
123 7285a491 2004-06-17 devnull close(xfd);
124 7285a491 2004-06-17 devnull return nil;
125 7285a491 2004-06-17 devnull }
126 7285a491 2004-06-17 devnull
127 7285a491 2004-06-17 devnull /* lowercase because of isostring */
128 7285a491 2004-06-17 devnull if(strstr(cd->iso.systemid, "iso9660") == nil
129 7285a491 2004-06-17 devnull && strstr(cd->iso.systemid, "utf8") == nil) {
130 7285a491 2004-06-17 devnull werrstr("unknown systemid %s", cd->iso.systemid);
131 7285a491 2004-06-17 devnull free(cd);
132 7285a491 2004-06-17 devnull close(fd);
133 7285a491 2004-06-17 devnull close(xfd);
134 7285a491 2004-06-17 devnull return nil;
135 7285a491 2004-06-17 devnull }
136 7285a491 2004-06-17 devnull
137 7285a491 2004-06-17 devnull if(strstr(cd->iso.systemid, "plan 9"))
138 7285a491 2004-06-17 devnull cd->flags |= CDplan9;
139 7285a491 2004-06-17 devnull if(strstr(cd->iso.systemid, "iso9660"))
140 7285a491 2004-06-17 devnull cd->flags |= CDconform;
141 7285a491 2004-06-17 devnull if(strstr(cd->iso.systemid, "rrip"))
142 7285a491 2004-06-17 devnull cd->flags |= CDrockridge;
143 7285a491 2004-06-17 devnull if(strstr(cd->iso.systemid, "boot"))
144 7285a491 2004-06-17 devnull cd->flags |= CDbootable;
145 7285a491 2004-06-17 devnull if(readjolietdesc(cd, &cd->joliet) == 0)
146 7285a491 2004-06-17 devnull cd->flags |= CDjoliet;
147 7285a491 2004-06-17 devnull if(hasdump(cd))
148 7285a491 2004-06-17 devnull cd->flags |= CDdump;
149 7285a491 2004-06-17 devnull
150 7285a491 2004-06-17 devnull return cd;
151 7285a491 2004-06-17 devnull }
152 7285a491 2004-06-17 devnull
153 7285a491 2004-06-17 devnull ulong
154 7285a491 2004-06-17 devnull big(void *a, int n)
155 7285a491 2004-06-17 devnull {
156 7285a491 2004-06-17 devnull uchar *p;
157 7285a491 2004-06-17 devnull ulong v;
158 7285a491 2004-06-17 devnull int i;
159 7285a491 2004-06-17 devnull
160 7285a491 2004-06-17 devnull p = a;
161 7285a491 2004-06-17 devnull v = 0;
162 7285a491 2004-06-17 devnull for(i=0; i<n; i++)
163 7285a491 2004-06-17 devnull v = (v<<8) | *p++;
164 7285a491 2004-06-17 devnull return v;
165 7285a491 2004-06-17 devnull }
166 7285a491 2004-06-17 devnull
167 7285a491 2004-06-17 devnull ulong
168 7285a491 2004-06-17 devnull little(void *a, int n)
169 7285a491 2004-06-17 devnull {
170 7285a491 2004-06-17 devnull uchar *p;
171 7285a491 2004-06-17 devnull ulong v;
172 7285a491 2004-06-17 devnull int i;
173 7285a491 2004-06-17 devnull
174 7285a491 2004-06-17 devnull p = a;
175 7285a491 2004-06-17 devnull v = 0;
176 7285a491 2004-06-17 devnull for(i=0; i<n; i++)
177 7285a491 2004-06-17 devnull v |= (*p++<<(i*8));
178 7285a491 2004-06-17 devnull return v;
179 7285a491 2004-06-17 devnull }
180 7285a491 2004-06-17 devnull
181 7285a491 2004-06-17 devnull void
182 7285a491 2004-06-17 devnull Creadblock(Cdimg *cd, void *buf, ulong block, ulong len)
183 7285a491 2004-06-17 devnull {
184 7285a491 2004-06-17 devnull assert(block != 0); /* nothing useful there */
185 7285a491 2004-06-17 devnull
186 7285a491 2004-06-17 devnull Bflush(&cd->bwr);
187 7285a491 2004-06-17 devnull if(Bseek(&cd->brd, block*Blocksize, 0) != block*Blocksize)
188 7285a491 2004-06-17 devnull sysfatal("error seeking to block %lud", block);
189 7285a491 2004-06-17 devnull if(Bread(&cd->brd, buf, len) != len)
190 7285a491 2004-06-17 devnull sysfatal("error reading %lud bytes at block %lud: %r %lld", len, block, Bseek(&cd->brd, 0, 2));
191 7285a491 2004-06-17 devnull }
192 7285a491 2004-06-17 devnull
193 7285a491 2004-06-17 devnull int
194 7285a491 2004-06-17 devnull parsedir(Cdimg *cd, Direc *d, uchar *buf, int len, char *(*cvtname)(uchar*, int))
195 7285a491 2004-06-17 devnull {
196 7285a491 2004-06-17 devnull enum { NAMELEN = 28 };
197 7285a491 2004-06-17 devnull char name[NAMELEN];
198 7285a491 2004-06-17 devnull uchar *p;
199 7285a491 2004-06-17 devnull Cdir *c;
200 7285a491 2004-06-17 devnull
201 7285a491 2004-06-17 devnull memset(d, 0, sizeof *d);
202 7285a491 2004-06-17 devnull
203 7285a491 2004-06-17 devnull c = (Cdir*)buf;
204 7285a491 2004-06-17 devnull
205 7285a491 2004-06-17 devnull if(c->len > len) {
206 7285a491 2004-06-17 devnull werrstr("buffer too small");
207 7285a491 2004-06-17 devnull return -1;
208 7285a491 2004-06-17 devnull }
209 7285a491 2004-06-17 devnull
210 7285a491 2004-06-17 devnull if(c->namelen == 1 && c->name[0] == '\0')
211 7285a491 2004-06-17 devnull d->name = atom(".");
212 7285a491 2004-06-17 devnull else if(c->namelen == 1 && c->name[0] == '\001')
213 7285a491 2004-06-17 devnull d->name = atom("..");
214 7285a491 2004-06-17 devnull else if(cvtname)
215 7285a491 2004-06-17 devnull d->name = cvtname(c->name, c->namelen);
216 7285a491 2004-06-17 devnull
217 7285a491 2004-06-17 devnull d->block = little(c->dloc, 4);
218 7285a491 2004-06-17 devnull d->length = little(c->dlen, 4);
219 7285a491 2004-06-17 devnull
220 7285a491 2004-06-17 devnull if(c->flags & 2)
221 7285a491 2004-06-17 devnull d->mode |= DMDIR;
222 7285a491 2004-06-17 devnull
223 7285a491 2004-06-17 devnull /*BUG: do we really need to parse the plan 9 fields? */
224 7285a491 2004-06-17 devnull /* plan 9 use fields */
225 7285a491 2004-06-17 devnull if((cd->flags & CDplan9) && cvtname == isostring
226 7285a491 2004-06-17 devnull && (c->namelen != 1 || c->name[0] > 1)) {
227 7285a491 2004-06-17 devnull p = buf+33+c->namelen;
228 7285a491 2004-06-17 devnull if((p-buf)&1)
229 7285a491 2004-06-17 devnull p++;
230 7285a491 2004-06-17 devnull assert(p < buf+c->len);
231 7285a491 2004-06-17 devnull assert(*p < NAMELEN);
232 7285a491 2004-06-17 devnull if(*p != 0) {
233 7285a491 2004-06-17 devnull memmove(name, p+1, *p);
234 7285a491 2004-06-17 devnull name[*p] = '\0';
235 7285a491 2004-06-17 devnull d->confname = d->name;
236 7285a491 2004-06-17 devnull d->name = atom(name);
237 7285a491 2004-06-17 devnull }
238 7285a491 2004-06-17 devnull p += *p+1;
239 7285a491 2004-06-17 devnull assert(*p < NAMELEN);
240 7285a491 2004-06-17 devnull memmove(name, p+1, *p);
241 7285a491 2004-06-17 devnull name[*p] = '\0';
242 7285a491 2004-06-17 devnull d->uid = atom(name);
243 7285a491 2004-06-17 devnull p += *p+1;
244 7285a491 2004-06-17 devnull assert(*p < NAMELEN);
245 7285a491 2004-06-17 devnull memmove(name, p+1, *p);
246 7285a491 2004-06-17 devnull name[*p] = '\0';
247 7285a491 2004-06-17 devnull d->gid = atom(name);
248 7285a491 2004-06-17 devnull p += *p+1;
249 7285a491 2004-06-17 devnull if((p-buf)&1)
250 7285a491 2004-06-17 devnull p++;
251 7285a491 2004-06-17 devnull d->mode = little(p, 4);
252 7285a491 2004-06-17 devnull }
253 7285a491 2004-06-17 devnull
254 7285a491 2004-06-17 devnull // BUG: rock ridge extensions
255 7285a491 2004-06-17 devnull return 0;
256 7285a491 2004-06-17 devnull }
257 7285a491 2004-06-17 devnull
258 7285a491 2004-06-17 devnull void
259 7285a491 2004-06-17 devnull setroot(Cdimg *cd, ulong block, ulong dloc, ulong dlen)
260 7285a491 2004-06-17 devnull {
261 7285a491 2004-06-17 devnull assert(block != 0);
262 7285a491 2004-06-17 devnull
263 7285a491 2004-06-17 devnull Cwseek(cd, block*Blocksize+offsetof(Cvoldesc, rootdir[0])+offsetof(Cdir, dloc[0]));
264 7285a491 2004-06-17 devnull Cputn(cd, dloc, 4);
265 7285a491 2004-06-17 devnull Cputn(cd, dlen, 4);
266 7285a491 2004-06-17 devnull }
267 7285a491 2004-06-17 devnull
268 7285a491 2004-06-17 devnull void
269 7285a491 2004-06-17 devnull setvolsize(Cdimg *cd, ulong block, ulong size)
270 7285a491 2004-06-17 devnull {
271 7285a491 2004-06-17 devnull assert(block != 0);
272 7285a491 2004-06-17 devnull
273 7285a491 2004-06-17 devnull Cwseek(cd, block*Blocksize+offsetof(Cvoldesc, volsize[0]));
274 7285a491 2004-06-17 devnull Cputn(cd, size, 4);
275 7285a491 2004-06-17 devnull }
276 7285a491 2004-06-17 devnull
277 7285a491 2004-06-17 devnull void
278 7285a491 2004-06-17 devnull setpathtable(Cdimg *cd, ulong block, ulong sz, ulong lloc, ulong bloc)
279 7285a491 2004-06-17 devnull {
280 7285a491 2004-06-17 devnull assert(block != 0);
281 7285a491 2004-06-17 devnull
282 7285a491 2004-06-17 devnull Cwseek(cd, block*Blocksize+offsetof(Cvoldesc, pathsize[0]));
283 7285a491 2004-06-17 devnull Cputn(cd, sz, 4);
284 7285a491 2004-06-17 devnull Cputnl(cd, lloc, 4);
285 7285a491 2004-06-17 devnull Cputnl(cd, 0, 4);
286 7285a491 2004-06-17 devnull Cputnm(cd, bloc, 4);
287 7285a491 2004-06-17 devnull Cputnm(cd, 0, 4);
288 7285a491 2004-06-17 devnull assert(Cwoffset(cd) == block*Blocksize+offsetof(Cvoldesc, rootdir[0]));
289 7285a491 2004-06-17 devnull }
290 7285a491 2004-06-17 devnull
291 7285a491 2004-06-17 devnull
292 7285a491 2004-06-17 devnull static void
293 7285a491 2004-06-17 devnull parsedesc(Voldesc *v, Cvoldesc *cv, char *(*string)(uchar*, int))
294 7285a491 2004-06-17 devnull {
295 7285a491 2004-06-17 devnull v->systemid = string(cv->systemid, sizeof cv->systemid);
296 7285a491 2004-06-17 devnull
297 7285a491 2004-06-17 devnull v->pathsize = little(cv->pathsize, 4);
298 7285a491 2004-06-17 devnull v->lpathloc = little(cv->lpathloc, 4);
299 7285a491 2004-06-17 devnull v->mpathloc = little(cv->mpathloc, 4);
300 7285a491 2004-06-17 devnull
301 7285a491 2004-06-17 devnull v->volumeset = string(cv->volumeset, sizeof cv->volumeset);
302 7285a491 2004-06-17 devnull v->publisher = string(cv->publisher, sizeof cv->publisher);
303 7285a491 2004-06-17 devnull v->preparer = string(cv->preparer, sizeof cv->preparer);
304 7285a491 2004-06-17 devnull v->application = string(cv->application, sizeof cv->application);
305 7285a491 2004-06-17 devnull
306 7285a491 2004-06-17 devnull v->abstract = string(cv->abstract, sizeof cv->abstract);
307 7285a491 2004-06-17 devnull v->biblio = string(cv->biblio, sizeof cv->biblio);
308 7285a491 2004-06-17 devnull v->notice = string(cv->notice, sizeof cv->notice);
309 7285a491 2004-06-17 devnull }
310 7285a491 2004-06-17 devnull
311 7285a491 2004-06-17 devnull static int
312 7285a491 2004-06-17 devnull readisodesc(Cdimg *cd, Voldesc *v)
313 7285a491 2004-06-17 devnull {
314 7285a491 2004-06-17 devnull static uchar magic[] = { 0x01, 'C', 'D', '0', '0', '1', 0x01, 0x00 };
315 7285a491 2004-06-17 devnull Cvoldesc cv;
316 7285a491 2004-06-17 devnull
317 7285a491 2004-06-17 devnull memset(v, 0, sizeof *v);
318 7285a491 2004-06-17 devnull
319 7285a491 2004-06-17 devnull Creadblock(cd, &cv, 16, sizeof cv);
320 7285a491 2004-06-17 devnull if(memcmp(cv.magic, magic, sizeof magic) != 0) {
321 7285a491 2004-06-17 devnull werrstr("bad pvd magic");
322 7285a491 2004-06-17 devnull return -1;
323 7285a491 2004-06-17 devnull }
324 7285a491 2004-06-17 devnull
325 7285a491 2004-06-17 devnull if(little(cv.blocksize, 2) != Blocksize) {
326 7285a491 2004-06-17 devnull werrstr("block size not %d", Blocksize);
327 7285a491 2004-06-17 devnull return -1;
328 7285a491 2004-06-17 devnull }
329 7285a491 2004-06-17 devnull
330 7285a491 2004-06-17 devnull cd->iso9660pvd = 16;
331 7285a491 2004-06-17 devnull parsedesc(v, &cv, isostring);
332 7285a491 2004-06-17 devnull
333 7285a491 2004-06-17 devnull return parsedir(cd, &v->root, cv.rootdir, sizeof cv.rootdir, isostring);
334 7285a491 2004-06-17 devnull }
335 7285a491 2004-06-17 devnull
336 7285a491 2004-06-17 devnull static int
337 7285a491 2004-06-17 devnull readjolietdesc(Cdimg *cd, Voldesc *v)
338 7285a491 2004-06-17 devnull {
339 7285a491 2004-06-17 devnull int i;
340 7285a491 2004-06-17 devnull static uchar magic[] = { 0x02, 'C', 'D', '0', '0', '1', 0x01, 0x00 };
341 7285a491 2004-06-17 devnull Cvoldesc cv;
342 7285a491 2004-06-17 devnull
343 7285a491 2004-06-17 devnull memset(v, 0, sizeof *v);
344 7285a491 2004-06-17 devnull
345 7285a491 2004-06-17 devnull for(i=16; i<24; i++) {
346 7285a491 2004-06-17 devnull Creadblock(cd, &cv, i, sizeof cv);
347 7285a491 2004-06-17 devnull if(memcmp(cv.magic, magic, sizeof magic) != 0)
348 7285a491 2004-06-17 devnull continue;
349 7285a491 2004-06-17 devnull if(cv.charset[0] != 0x25 || cv.charset[1] != 0x2F
350 7285a491 2004-06-17 devnull || (cv.charset[2] != 0x40 && cv.charset[2] != 0x43 && cv.charset[2] != 0x45))
351 7285a491 2004-06-17 devnull continue;
352 7285a491 2004-06-17 devnull break;
353 7285a491 2004-06-17 devnull }
354 7285a491 2004-06-17 devnull
355 7285a491 2004-06-17 devnull if(i==24) {
356 7285a491 2004-06-17 devnull werrstr("could not find Joliet SVD");
357 7285a491 2004-06-17 devnull return -1;
358 7285a491 2004-06-17 devnull }
359 7285a491 2004-06-17 devnull
360 7285a491 2004-06-17 devnull if(little(cv.blocksize, 2) != Blocksize) {
361 7285a491 2004-06-17 devnull werrstr("block size not %d", Blocksize);
362 7285a491 2004-06-17 devnull return -1;
363 7285a491 2004-06-17 devnull }
364 7285a491 2004-06-17 devnull
365 7285a491 2004-06-17 devnull cd->jolietsvd = i;
366 7285a491 2004-06-17 devnull parsedesc(v, &cv, jolietstring);
367 7285a491 2004-06-17 devnull
368 7285a491 2004-06-17 devnull return parsedir(cd, &v->root, cv.rootdir, sizeof cv.rootdir, jolietstring);
369 7285a491 2004-06-17 devnull }
370 7285a491 2004-06-17 devnull
371 7285a491 2004-06-17 devnull /*
372 7285a491 2004-06-17 devnull * CD image buffering routines.
373 7285a491 2004-06-17 devnull */
374 7285a491 2004-06-17 devnull void
375 7285a491 2004-06-17 devnull Cputc(Cdimg *cd, int c)
376 7285a491 2004-06-17 devnull {
377 7285a491 2004-06-17 devnull assert(Boffset(&cd->bwr) >= 16*Blocksize || c == 0);
378 7285a491 2004-06-17 devnull
379 7285a491 2004-06-17 devnull if(Boffset(&cd->bwr) == 0x9962)
380 7285a491 2004-06-17 devnull if(c >= 256) abort();
381 7285a491 2004-06-17 devnull if(Bputc(&cd->bwr, c) < 0)
382 7285a491 2004-06-17 devnull sysfatal("Bputc: %r");
383 7285a491 2004-06-17 devnull Bflush(&cd->brd);
384 7285a491 2004-06-17 devnull }
385 7285a491 2004-06-17 devnull
386 7285a491 2004-06-17 devnull void
387 7285a491 2004-06-17 devnull Cputnl(Cdimg *cd, ulong val, int size)
388 7285a491 2004-06-17 devnull {
389 7285a491 2004-06-17 devnull switch(size) {
390 7285a491 2004-06-17 devnull default:
391 7285a491 2004-06-17 devnull sysfatal("bad size %d in bputnl", size);
392 7285a491 2004-06-17 devnull case 2:
393 7285a491 2004-06-17 devnull Cputc(cd, val);
394 7285a491 2004-06-17 devnull Cputc(cd, val>>8);
395 7285a491 2004-06-17 devnull break;
396 7285a491 2004-06-17 devnull case 4:
397 7285a491 2004-06-17 devnull Cputc(cd, val);
398 7285a491 2004-06-17 devnull Cputc(cd, val>>8);
399 7285a491 2004-06-17 devnull Cputc(cd, val>>16);
400 7285a491 2004-06-17 devnull Cputc(cd, val>>24);
401 7285a491 2004-06-17 devnull break;
402 7285a491 2004-06-17 devnull }
403 7285a491 2004-06-17 devnull }
404 7285a491 2004-06-17 devnull
405 7285a491 2004-06-17 devnull void
406 7285a491 2004-06-17 devnull Cputnm(Cdimg *cd, ulong val, int size)
407 7285a491 2004-06-17 devnull {
408 7285a491 2004-06-17 devnull switch(size) {
409 7285a491 2004-06-17 devnull default:
410 7285a491 2004-06-17 devnull sysfatal("bad size %d in bputnl", size);
411 7285a491 2004-06-17 devnull case 2:
412 7285a491 2004-06-17 devnull Cputc(cd, val>>8);
413 7285a491 2004-06-17 devnull Cputc(cd, val);
414 7285a491 2004-06-17 devnull break;
415 7285a491 2004-06-17 devnull case 4:
416 7285a491 2004-06-17 devnull Cputc(cd, val>>24);
417 7285a491 2004-06-17 devnull Cputc(cd, val>>16);
418 7285a491 2004-06-17 devnull Cputc(cd, val>>8);
419 7285a491 2004-06-17 devnull Cputc(cd, val);
420 7285a491 2004-06-17 devnull break;
421 7285a491 2004-06-17 devnull }
422 7285a491 2004-06-17 devnull }
423 7285a491 2004-06-17 devnull
424 7285a491 2004-06-17 devnull void
425 7285a491 2004-06-17 devnull Cputn(Cdimg *cd, long val, int size)
426 7285a491 2004-06-17 devnull {
427 7285a491 2004-06-17 devnull Cputnl(cd, val, size);
428 7285a491 2004-06-17 devnull Cputnm(cd, val, size);
429 7285a491 2004-06-17 devnull }
430 7285a491 2004-06-17 devnull
431 7285a491 2004-06-17 devnull /*
432 7285a491 2004-06-17 devnull * ASCII/UTF string writing
433 7285a491 2004-06-17 devnull */
434 7285a491 2004-06-17 devnull void
435 7285a491 2004-06-17 devnull Crepeat(Cdimg *cd, int c, int n)
436 7285a491 2004-06-17 devnull {
437 7285a491 2004-06-17 devnull while(n-- > 0)
438 7285a491 2004-06-17 devnull Cputc(cd, c);
439 7285a491 2004-06-17 devnull }
440 7285a491 2004-06-17 devnull
441 7285a491 2004-06-17 devnull void
442 7285a491 2004-06-17 devnull Cputs(Cdimg *cd, char *s, int size)
443 7285a491 2004-06-17 devnull {
444 7285a491 2004-06-17 devnull int n;
445 7285a491 2004-06-17 devnull
446 7285a491 2004-06-17 devnull if(s == nil) {
447 7285a491 2004-06-17 devnull Crepeat(cd, ' ', size);
448 7285a491 2004-06-17 devnull return;
449 7285a491 2004-06-17 devnull }
450 7285a491 2004-06-17 devnull
451 7285a491 2004-06-17 devnull for(n=0; n<size && *s; n++)
452 7285a491 2004-06-17 devnull Cputc(cd, *s++);
453 7285a491 2004-06-17 devnull if(n<size)
454 7285a491 2004-06-17 devnull Crepeat(cd, ' ', size-n);
455 7285a491 2004-06-17 devnull }
456 7285a491 2004-06-17 devnull
457 7285a491 2004-06-17 devnull void
458 7285a491 2004-06-17 devnull Cwrite(Cdimg *cd, void *buf, int n)
459 7285a491 2004-06-17 devnull {
460 7285a491 2004-06-17 devnull assert(Boffset(&cd->bwr) >= 16*Blocksize);
461 7285a491 2004-06-17 devnull
462 7285a491 2004-06-17 devnull if(Bwrite(&cd->bwr, buf, n) != n)
463 7285a491 2004-06-17 devnull sysfatal("Bwrite: %r");
464 7285a491 2004-06-17 devnull Bflush(&cd->brd);
465 7285a491 2004-06-17 devnull }
466 7285a491 2004-06-17 devnull
467 7285a491 2004-06-17 devnull void
468 7285a491 2004-06-17 devnull Cputr(Cdimg *cd, Rune r)
469 7285a491 2004-06-17 devnull {
470 7285a491 2004-06-17 devnull Cputc(cd, r>>8);
471 7285a491 2004-06-17 devnull Cputc(cd, r);
472 7285a491 2004-06-17 devnull }
473 7285a491 2004-06-17 devnull
474 7285a491 2004-06-17 devnull void
475 7285a491 2004-06-17 devnull Crepeatr(Cdimg *cd, Rune r, int n)
476 7285a491 2004-06-17 devnull {
477 7285a491 2004-06-17 devnull int i;
478 7285a491 2004-06-17 devnull
479 7285a491 2004-06-17 devnull for(i=0; i<n; i++)
480 7285a491 2004-06-17 devnull Cputr(cd, r);
481 7285a491 2004-06-17 devnull }
482 7285a491 2004-06-17 devnull
483 7285a491 2004-06-17 devnull void
484 7285a491 2004-06-17 devnull Cputrs(Cdimg *cd, Rune *s, int osize)
485 7285a491 2004-06-17 devnull {
486 7285a491 2004-06-17 devnull int n, size;
487 7285a491 2004-06-17 devnull
488 7285a491 2004-06-17 devnull size = osize/2;
489 7285a491 2004-06-17 devnull if(s == nil)
490 7285a491 2004-06-17 devnull Crepeatr(cd, (Rune)' ', size);
491 7285a491 2004-06-17 devnull else {
492 7285a491 2004-06-17 devnull for(n=0; *s && n<size; n++)
493 7285a491 2004-06-17 devnull Cputr(cd, *s++);
494 7285a491 2004-06-17 devnull if(n<size)
495 7285a491 2004-06-17 devnull Crepeatr(cd, ' ', size-n);
496 7285a491 2004-06-17 devnull }
497 7285a491 2004-06-17 devnull if(osize&1)
498 7285a491 2004-06-17 devnull Cputc(cd, 0); /* what else can we do? */
499 7285a491 2004-06-17 devnull }
500 7285a491 2004-06-17 devnull
501 7285a491 2004-06-17 devnull void
502 7285a491 2004-06-17 devnull Cputrscvt(Cdimg *cd, char *s, int size)
503 7285a491 2004-06-17 devnull {
504 7285a491 2004-06-17 devnull Rune r[256];
505 7285a491 2004-06-17 devnull
506 7285a491 2004-06-17 devnull strtorune(r, s);
507 7285a491 2004-06-17 devnull Cputrs(cd, strtorune(r, s), size);
508 7285a491 2004-06-17 devnull }
509 7285a491 2004-06-17 devnull
510 7285a491 2004-06-17 devnull void
511 7285a491 2004-06-17 devnull Cpadblock(Cdimg *cd)
512 7285a491 2004-06-17 devnull {
513 7285a491 2004-06-17 devnull int n;
514 7285a491 2004-06-17 devnull ulong nb;
515 7285a491 2004-06-17 devnull
516 7285a491 2004-06-17 devnull n = Blocksize - (Boffset(&cd->bwr) % Blocksize);
517 7285a491 2004-06-17 devnull if(n != Blocksize)
518 7285a491 2004-06-17 devnull Crepeat(cd, 0, n);
519 7285a491 2004-06-17 devnull
520 7285a491 2004-06-17 devnull nb = Boffset(&cd->bwr)/Blocksize;
521 7285a491 2004-06-17 devnull assert(nb != 0);
522 7285a491 2004-06-17 devnull if(nb > cd->nextblock)
523 7285a491 2004-06-17 devnull cd->nextblock = nb;
524 7285a491 2004-06-17 devnull }
525 7285a491 2004-06-17 devnull
526 7285a491 2004-06-17 devnull void
527 7285a491 2004-06-17 devnull Cputdate(Cdimg *cd, ulong ust)
528 7285a491 2004-06-17 devnull {
529 7285a491 2004-06-17 devnull Tm *tm;
530 7285a491 2004-06-17 devnull
531 7285a491 2004-06-17 devnull if(ust == 0) {
532 7285a491 2004-06-17 devnull Crepeat(cd, 0, 7);
533 7285a491 2004-06-17 devnull return;
534 7285a491 2004-06-17 devnull }
535 7285a491 2004-06-17 devnull tm = gmtime(ust);
536 7285a491 2004-06-17 devnull Cputc(cd, tm->year);
537 7285a491 2004-06-17 devnull Cputc(cd, tm->mon+1);
538 7285a491 2004-06-17 devnull Cputc(cd, tm->mday);
539 7285a491 2004-06-17 devnull Cputc(cd, tm->hour);
540 7285a491 2004-06-17 devnull Cputc(cd, tm->min);
541 7285a491 2004-06-17 devnull Cputc(cd, tm->sec);
542 7285a491 2004-06-17 devnull Cputc(cd, 0);
543 7285a491 2004-06-17 devnull }
544 7285a491 2004-06-17 devnull
545 7285a491 2004-06-17 devnull void
546 7285a491 2004-06-17 devnull Cputdate1(Cdimg *cd, ulong ust)
547 7285a491 2004-06-17 devnull {
548 7285a491 2004-06-17 devnull Tm *tm;
549 7285a491 2004-06-17 devnull char str[20];
550 7285a491 2004-06-17 devnull
551 7285a491 2004-06-17 devnull if(ust == 0) {
552 7285a491 2004-06-17 devnull Crepeat(cd, '0', 16);
553 7285a491 2004-06-17 devnull Cputc(cd, 0);
554 7285a491 2004-06-17 devnull return;
555 7285a491 2004-06-17 devnull }
556 7285a491 2004-06-17 devnull tm = gmtime(ust);
557 7285a491 2004-06-17 devnull sprint(str, "%.4d%.2d%.2d%.2d%.2d%.4d",
558 7285a491 2004-06-17 devnull tm->year+1900,
559 7285a491 2004-06-17 devnull tm->mon+1,
560 7285a491 2004-06-17 devnull tm->mday,
561 7285a491 2004-06-17 devnull tm->hour,
562 7285a491 2004-06-17 devnull tm->min,
563 7285a491 2004-06-17 devnull tm->sec*100);
564 7285a491 2004-06-17 devnull Cputs(cd, str, 16);
565 7285a491 2004-06-17 devnull Cputc(cd, 0);
566 7285a491 2004-06-17 devnull }
567 7285a491 2004-06-17 devnull
568 7285a491 2004-06-17 devnull void
569 7285a491 2004-06-17 devnull Cwseek(Cdimg *cd, ulong offset)
570 7285a491 2004-06-17 devnull {
571 7285a491 2004-06-17 devnull Bseek(&cd->bwr, offset, 0);
572 7285a491 2004-06-17 devnull }
573 7285a491 2004-06-17 devnull
574 7285a491 2004-06-17 devnull ulong
575 7285a491 2004-06-17 devnull Cwoffset(Cdimg *cd)
576 7285a491 2004-06-17 devnull {
577 7285a491 2004-06-17 devnull return Boffset(&cd->bwr);
578 7285a491 2004-06-17 devnull }
579 7285a491 2004-06-17 devnull
580 7285a491 2004-06-17 devnull void
581 7285a491 2004-06-17 devnull Cwflush(Cdimg *cd)
582 7285a491 2004-06-17 devnull {
583 7285a491 2004-06-17 devnull Bflush(&cd->bwr);
584 7285a491 2004-06-17 devnull }
585 7285a491 2004-06-17 devnull
586 7285a491 2004-06-17 devnull ulong
587 7285a491 2004-06-17 devnull Croffset(Cdimg *cd)
588 7285a491 2004-06-17 devnull {
589 7285a491 2004-06-17 devnull return Boffset(&cd->brd);
590 7285a491 2004-06-17 devnull }
591 7285a491 2004-06-17 devnull
592 7285a491 2004-06-17 devnull void
593 7285a491 2004-06-17 devnull Crseek(Cdimg *cd, ulong offset)
594 7285a491 2004-06-17 devnull {
595 7285a491 2004-06-17 devnull Bseek(&cd->brd, offset, 0);
596 7285a491 2004-06-17 devnull }
597 7285a491 2004-06-17 devnull
598 7285a491 2004-06-17 devnull int
599 7285a491 2004-06-17 devnull Cgetc(Cdimg *cd)
600 7285a491 2004-06-17 devnull {
601 7285a491 2004-06-17 devnull int c;
602 7285a491 2004-06-17 devnull
603 7285a491 2004-06-17 devnull Cwflush(cd);
604 7285a491 2004-06-17 devnull if((c = Bgetc(&cd->brd)) == Beof) {
605 7285a491 2004-06-17 devnull fprint(2, "getc at %lud\n", Croffset(cd));
606 7285a491 2004-06-17 devnull assert(0);
607 7285a491 2004-06-17 devnull //sysfatal("Bgetc: %r");
608 7285a491 2004-06-17 devnull }
609 7285a491 2004-06-17 devnull return c;
610 7285a491 2004-06-17 devnull }
611 7285a491 2004-06-17 devnull
612 7285a491 2004-06-17 devnull void
613 7285a491 2004-06-17 devnull Cread(Cdimg *cd, void *buf, int n)
614 7285a491 2004-06-17 devnull {
615 7285a491 2004-06-17 devnull Cwflush(cd);
616 7285a491 2004-06-17 devnull if(Bread(&cd->brd, buf, n) != n)
617 7285a491 2004-06-17 devnull sysfatal("Bread: %r");
618 7285a491 2004-06-17 devnull }
619 7285a491 2004-06-17 devnull
620 7285a491 2004-06-17 devnull char*
621 7285a491 2004-06-17 devnull Crdline(Cdimg *cd, int c)
622 7285a491 2004-06-17 devnull {
623 7285a491 2004-06-17 devnull Cwflush(cd);
624 7285a491 2004-06-17 devnull return Brdline(&cd->brd, c);
625 7285a491 2004-06-17 devnull }
626 7285a491 2004-06-17 devnull
627 7285a491 2004-06-17 devnull int
628 7285a491 2004-06-17 devnull Clinelen(Cdimg *cd)
629 7285a491 2004-06-17 devnull {
630 7285a491 2004-06-17 devnull return Blinelen(&cd->brd);
631 7285a491 2004-06-17 devnull }
632 7285a491 2004-06-17 devnull