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>
6 7285a491 2004-06-17 devnull #include "iso9660.h"
8 7285a491 2004-06-17 devnull static int readisodesc(Cdimg*, Voldesc*);
9 7285a491 2004-06-17 devnull static int readjolietdesc(Cdimg*, Voldesc*);
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.
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
21 7285a491 2004-06-17 devnull createcd(char *file, Cdinfo info)
23 7285a491 2004-06-17 devnull int fd, xfd;
24 7285a491 2004-06-17 devnull Cdimg *cd;
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;
31 7285a491 2004-06-17 devnull if((fd = create(file, ORDWR, 0666)) < 0)
32 7285a491 2004-06-17 devnull return nil;
34 7285a491 2004-06-17 devnull cd = emalloc(sizeof *cd);
35 7285a491 2004-06-17 devnull cd->file = atom(file);
37 7285a491 2004-06-17 devnull Binit(&cd->brd, fd, OREAD);
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);
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);
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;
63 7285a491 2004-06-17 devnull Cputendvd(cd);
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;
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);
74 7285a491 2004-06-17 devnull if(info.flags & CDconform)
75 7285a491 2004-06-17 devnull cd->flags |= CDconform;
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);
81 7285a491 2004-06-17 devnull return cd;
85 7285a491 2004-06-17 devnull opencd(char *file, Cdinfo info)
87 7285a491 2004-06-17 devnull int fd, xfd;
88 7285a491 2004-06-17 devnull Cdimg *cd;
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);
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;
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;
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);
114 7285a491 2004-06-17 devnull Binit(&cd->brd, fd, OREAD);
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);
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;
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;
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;
150 7285a491 2004-06-17 devnull return cd;
154 7285a491 2004-06-17 devnull big(void *a, int n)
156 7285a491 2004-06-17 devnull uchar *p;
157 7285a491 2004-06-17 devnull ulong v;
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;
168 7285a491 2004-06-17 devnull little(void *a, int n)
170 7285a491 2004-06-17 devnull uchar *p;
171 7285a491 2004-06-17 devnull ulong v;
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;
182 7285a491 2004-06-17 devnull Creadblock(Cdimg *cd, void *buf, ulong block, ulong len)
184 7285a491 2004-06-17 devnull assert(block != 0); /* nothing useful there */
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));
194 7285a491 2004-06-17 devnull parsedir(Cdimg *cd, Direc *d, uchar *buf, int len, char *(*cvtname)(uchar*, int))
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;
201 7285a491 2004-06-17 devnull memset(d, 0, sizeof *d);
203 7285a491 2004-06-17 devnull c = (Cdir*)buf;
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;
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);
217 7285a491 2004-06-17 devnull d->block = little(c->dloc, 4);
218 7285a491 2004-06-17 devnull d->length = little(c->dlen, 4);
220 7285a491 2004-06-17 devnull if(c->flags & 2)
221 7285a491 2004-06-17 devnull d->mode |= DMDIR;
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)
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);
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)
251 7285a491 2004-06-17 devnull d->mode = little(p, 4);
254 7285a491 2004-06-17 devnull // BUG: rock ridge extensions
255 7285a491 2004-06-17 devnull return 0;
259 7285a491 2004-06-17 devnull setroot(Cdimg *cd, ulong block, ulong dloc, ulong dlen)
261 7285a491 2004-06-17 devnull assert(block != 0);
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);
269 7285a491 2004-06-17 devnull setvolsize(Cdimg *cd, ulong block, ulong size)
271 7285a491 2004-06-17 devnull assert(block != 0);
273 7285a491 2004-06-17 devnull Cwseek(cd, block*Blocksize+offsetof(Cvoldesc, volsize[0]));
274 7285a491 2004-06-17 devnull Cputn(cd, size, 4);
278 7285a491 2004-06-17 devnull setpathtable(Cdimg *cd, ulong block, ulong sz, ulong lloc, ulong bloc)
280 7285a491 2004-06-17 devnull assert(block != 0);
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]));
292 7285a491 2004-06-17 devnull static void
293 7285a491 2004-06-17 devnull parsedesc(Voldesc *v, Cvoldesc *cv, char *(*string)(uchar*, int))
295 7285a491 2004-06-17 devnull v->systemid = string(cv->systemid, sizeof cv->systemid);
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);
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);
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);
311 7285a491 2004-06-17 devnull static int
312 7285a491 2004-06-17 devnull readisodesc(Cdimg *cd, Voldesc *v)
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;
317 7285a491 2004-06-17 devnull memset(v, 0, sizeof *v);
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;
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;
330 7285a491 2004-06-17 devnull cd->iso9660pvd = 16;
331 7285a491 2004-06-17 devnull parsedesc(v, &cv, isostring);
333 7285a491 2004-06-17 devnull return parsedir(cd, &v->root, cv.rootdir, sizeof cv.rootdir, isostring);
336 7285a491 2004-06-17 devnull static int
337 7285a491 2004-06-17 devnull readjolietdesc(Cdimg *cd, Voldesc *v)
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;
343 7285a491 2004-06-17 devnull memset(v, 0, sizeof *v);
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;
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;
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;
365 7285a491 2004-06-17 devnull cd->jolietsvd = i;
366 7285a491 2004-06-17 devnull parsedesc(v, &cv, jolietstring);
368 7285a491 2004-06-17 devnull return parsedir(cd, &v->root, cv.rootdir, sizeof cv.rootdir, jolietstring);
372 7285a491 2004-06-17 devnull * CD image buffering routines.
375 7285a491 2004-06-17 devnull Cputc(Cdimg *cd, int c)
377 7285a491 2004-06-17 devnull assert(Boffset(&cd->bwr) >= 16*Blocksize || c == 0);
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);
387 7285a491 2004-06-17 devnull Cputnl(Cdimg *cd, ulong val, int size)
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);
393 7285a491 2004-06-17 devnull Cputc(cd, val);
394 7285a491 2004-06-17 devnull Cputc(cd, val>>8);
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);
406 7285a491 2004-06-17 devnull Cputnm(Cdimg *cd, ulong val, int size)
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);
412 7285a491 2004-06-17 devnull Cputc(cd, val>>8);
413 7285a491 2004-06-17 devnull Cputc(cd, val);
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);
425 7285a491 2004-06-17 devnull Cputn(Cdimg *cd, long val, int size)
427 7285a491 2004-06-17 devnull Cputnl(cd, val, size);
428 7285a491 2004-06-17 devnull Cputnm(cd, val, size);
432 7285a491 2004-06-17 devnull * ASCII/UTF string writing
435 7285a491 2004-06-17 devnull Crepeat(Cdimg *cd, int c, int n)
437 7285a491 2004-06-17 devnull while(n-- > 0)
438 7285a491 2004-06-17 devnull Cputc(cd, c);
442 7285a491 2004-06-17 devnull Cputs(Cdimg *cd, char *s, int size)
446 7285a491 2004-06-17 devnull if(s == nil) {
447 7285a491 2004-06-17 devnull Crepeat(cd, ' ', size);
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);
458 7285a491 2004-06-17 devnull Cwrite(Cdimg *cd, void *buf, int n)
460 7285a491 2004-06-17 devnull assert(Boffset(&cd->bwr) >= 16*Blocksize);
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);
468 7285a491 2004-06-17 devnull Cputr(Cdimg *cd, Rune r)
470 7285a491 2004-06-17 devnull Cputc(cd, r>>8);
471 7285a491 2004-06-17 devnull Cputc(cd, r);
475 7285a491 2004-06-17 devnull Crepeatr(Cdimg *cd, Rune r, int n)
479 7285a491 2004-06-17 devnull for(i=0; i<n; i++)
480 7285a491 2004-06-17 devnull Cputr(cd, r);
484 7285a491 2004-06-17 devnull Cputrs(Cdimg *cd, Rune *s, int osize)
486 7285a491 2004-06-17 devnull int n, size;
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);
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);
497 7285a491 2004-06-17 devnull if(osize&1)
498 7285a491 2004-06-17 devnull Cputc(cd, 0); /* what else can we do? */
502 7285a491 2004-06-17 devnull Cputrscvt(Cdimg *cd, char *s, int size)
504 7285a491 2004-06-17 devnull Rune r[256];
506 7285a491 2004-06-17 devnull strtorune(r, s);
507 7285a491 2004-06-17 devnull Cputrs(cd, strtorune(r, s), size);
511 7285a491 2004-06-17 devnull Cpadblock(Cdimg *cd)
514 7285a491 2004-06-17 devnull ulong nb;
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);
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;
527 7285a491 2004-06-17 devnull Cputdate(Cdimg *cd, ulong ust)
531 7285a491 2004-06-17 devnull if(ust == 0) {
532 7285a491 2004-06-17 devnull Crepeat(cd, 0, 7);
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);
546 7285a491 2004-06-17 devnull Cputdate1(Cdimg *cd, ulong ust)
549 7285a491 2004-06-17 devnull char str[20];
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);
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);
569 7285a491 2004-06-17 devnull Cwseek(Cdimg *cd, ulong offset)
571 7285a491 2004-06-17 devnull Bseek(&cd->bwr, offset, 0);
575 7285a491 2004-06-17 devnull Cwoffset(Cdimg *cd)
577 7285a491 2004-06-17 devnull return Boffset(&cd->bwr);
581 7285a491 2004-06-17 devnull Cwflush(Cdimg *cd)
583 7285a491 2004-06-17 devnull Bflush(&cd->bwr);
587 7285a491 2004-06-17 devnull Croffset(Cdimg *cd)
589 7285a491 2004-06-17 devnull return Boffset(&cd->brd);
593 7285a491 2004-06-17 devnull Crseek(Cdimg *cd, ulong offset)
595 7285a491 2004-06-17 devnull Bseek(&cd->brd, offset, 0);
599 7285a491 2004-06-17 devnull Cgetc(Cdimg *cd)
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");
609 7285a491 2004-06-17 devnull return c;
613 7285a491 2004-06-17 devnull Cread(Cdimg *cd, void *buf, int n)
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");
621 7285a491 2004-06-17 devnull Crdline(Cdimg *cd, int c)
623 7285a491 2004-06-17 devnull Cwflush(cd);
624 7285a491 2004-06-17 devnull return Brdline(&cd->brd, c);
628 7285a491 2004-06-17 devnull Clinelen(Cdimg *cd)
630 7285a491 2004-06-17 devnull return Blinelen(&cd->brd);