Blame


1 6f4d00ee 2013-09-23 0intro /*
2 6f4d00ee 2013-09-23 0intro * Initialize a fossil file system from an ISO9660 image already in the
3 6f4d00ee 2013-09-23 0intro * file system. This is a fairly bizarre thing to do, but it lets us generate
4 fa325e9b 2020-01-10 cross * installation CDs that double as valid Plan 9 disk partitions.
5 6f4d00ee 2013-09-23 0intro * People having trouble booting the CD can just copy it into a disk
6 6f4d00ee 2013-09-23 0intro * partition and you've got a working Plan 9 system.
7 6f4d00ee 2013-09-23 0intro *
8 6f4d00ee 2013-09-23 0intro * I've tried hard to keep all the associated cruft in this file.
9 6f4d00ee 2013-09-23 0intro * If you deleted this file and cut out the three calls into it from flfmt.c,
10 6f4d00ee 2013-09-23 0intro * no traces would remain.
11 6f4d00ee 2013-09-23 0intro */
12 6f4d00ee 2013-09-23 0intro
13 6f4d00ee 2013-09-23 0intro #include "stdinc.h"
14 6f4d00ee 2013-09-23 0intro #include "dat.h"
15 6f4d00ee 2013-09-23 0intro #include "fns.h"
16 6f4d00ee 2013-09-23 0intro #include "flfmt9660.h"
17 6f4d00ee 2013-09-23 0intro #include <bio.h>
18 6f4d00ee 2013-09-23 0intro #include <ctype.h>
19 6f4d00ee 2013-09-23 0intro
20 6f4d00ee 2013-09-23 0intro static Biobuf *b;
21 6f4d00ee 2013-09-23 0intro
22 6f4d00ee 2013-09-23 0intro enum{
23 6f4d00ee 2013-09-23 0intro Tag = 0x96609660,
24 6f4d00ee 2013-09-23 0intro Blocksize = 2048,
25 6f4d00ee 2013-09-23 0intro };
26 6f4d00ee 2013-09-23 0intro
27 6f4d00ee 2013-09-23 0intro #pragma varargck type "s" uchar*
28 6f4d00ee 2013-09-23 0intro #pragma varargck type "L" uchar*
29 6f4d00ee 2013-09-23 0intro #pragma varargck type "B" uchar*
30 6f4d00ee 2013-09-23 0intro #pragma varargck type "N" uchar*
31 4b576658 2013-09-23 0intro #pragma varargck type "C" uchar*
32 6f4d00ee 2013-09-23 0intro #pragma varargck type "D" uchar*
33 6f4d00ee 2013-09-23 0intro
34 6f4d00ee 2013-09-23 0intro typedef struct Voldesc Voldesc;
35 6f4d00ee 2013-09-23 0intro struct Voldesc {
36 6f4d00ee 2013-09-23 0intro uchar magic[8]; /* 0x01, "CD001", 0x01, 0x00 */
37 6f4d00ee 2013-09-23 0intro uchar systemid[32]; /* system identifier */
38 6f4d00ee 2013-09-23 0intro uchar volumeid[32]; /* volume identifier */
39 6f4d00ee 2013-09-23 0intro uchar unused[8]; /* character set in secondary desc */
40 6f4d00ee 2013-09-23 0intro uchar volsize[8]; /* volume size */
41 6f4d00ee 2013-09-23 0intro uchar charset[32];
42 6f4d00ee 2013-09-23 0intro uchar volsetsize[4]; /* volume set size = 1 */
43 6f4d00ee 2013-09-23 0intro uchar volseqnum[4]; /* volume sequence number = 1 */
44 6f4d00ee 2013-09-23 0intro uchar blocksize[4]; /* logical block size */
45 6f4d00ee 2013-09-23 0intro uchar pathsize[8]; /* path table size */
46 6f4d00ee 2013-09-23 0intro uchar lpathloc[4]; /* Lpath */
47 6f4d00ee 2013-09-23 0intro uchar olpathloc[4]; /* optional Lpath */
48 6f4d00ee 2013-09-23 0intro uchar mpathloc[4]; /* Mpath */
49 6f4d00ee 2013-09-23 0intro uchar ompathloc[4]; /* optional Mpath */
50 6f4d00ee 2013-09-23 0intro uchar rootdir[34]; /* root directory */
51 6f4d00ee 2013-09-23 0intro uchar volsetid[128]; /* volume set identifier */
52 6f4d00ee 2013-09-23 0intro uchar publisher[128];
53 6f4d00ee 2013-09-23 0intro uchar prepid[128]; /* data preparer identifier */
54 6f4d00ee 2013-09-23 0intro uchar applid[128]; /* application identifier */
55 6f4d00ee 2013-09-23 0intro uchar notice[37]; /* copyright notice file */
56 6f4d00ee 2013-09-23 0intro uchar abstract[37]; /* abstract file */
57 6f4d00ee 2013-09-23 0intro uchar biblio[37]; /* bibliographic file */
58 6f4d00ee 2013-09-23 0intro uchar cdate[17]; /* creation date */
59 6f4d00ee 2013-09-23 0intro uchar mdate[17]; /* modification date */
60 6f4d00ee 2013-09-23 0intro uchar xdate[17]; /* expiration date */
61 6f4d00ee 2013-09-23 0intro uchar edate[17]; /* effective date */
62 6f4d00ee 2013-09-23 0intro uchar fsvers; /* file system version = 1 */
63 6f4d00ee 2013-09-23 0intro };
64 6f4d00ee 2013-09-23 0intro
65 6f4d00ee 2013-09-23 0intro typedef struct Cdir Cdir;
66 6f4d00ee 2013-09-23 0intro struct Cdir {
67 6f4d00ee 2013-09-23 0intro uchar len;
68 6f4d00ee 2013-09-23 0intro uchar xlen;
69 6f4d00ee 2013-09-23 0intro uchar dloc[8];
70 6f4d00ee 2013-09-23 0intro uchar dlen[8];
71 6f4d00ee 2013-09-23 0intro uchar date[7];
72 6f4d00ee 2013-09-23 0intro uchar flags;
73 6f4d00ee 2013-09-23 0intro uchar unitsize;
74 6f4d00ee 2013-09-23 0intro uchar gapsize;
75 6f4d00ee 2013-09-23 0intro uchar volseqnum[4];
76 6f4d00ee 2013-09-23 0intro uchar namelen;
77 6f4d00ee 2013-09-23 0intro uchar name[1]; /* chumminess */
78 6f4d00ee 2013-09-23 0intro };
79 6f4d00ee 2013-09-23 0intro #pragma varargck type "D" Cdir*
80 6f4d00ee 2013-09-23 0intro
81 6f4d00ee 2013-09-23 0intro static int
82 6f4d00ee 2013-09-23 0intro Dfmt(Fmt *fmt)
83 6f4d00ee 2013-09-23 0intro {
84 6f4d00ee 2013-09-23 0intro char buf[128];
85 6f4d00ee 2013-09-23 0intro Cdir *c;
86 6f4d00ee 2013-09-23 0intro
87 6f4d00ee 2013-09-23 0intro c = va_arg(fmt->args, Cdir*);
88 6f4d00ee 2013-09-23 0intro if(c->namelen == 1 && c->name[0] == '\0' || c->name[0] == '\001') {
89 6f4d00ee 2013-09-23 0intro snprint(buf, sizeof buf, ".%s dloc %.4N dlen %.4N",
90 6f4d00ee 2013-09-23 0intro c->name[0] ? "." : "", c->dloc, c->dlen);
91 6f4d00ee 2013-09-23 0intro } else {
92 4b576658 2013-09-23 0intro snprint(buf, sizeof buf, "%.*C dloc %.4N dlen %.4N", c->namelen, c->name,
93 6f4d00ee 2013-09-23 0intro c->dloc, c->dlen);
94 6f4d00ee 2013-09-23 0intro }
95 6f4d00ee 2013-09-23 0intro fmtstrcpy(fmt, buf);
96 6f4d00ee 2013-09-23 0intro return 0;
97 6f4d00ee 2013-09-23 0intro }
98 6f4d00ee 2013-09-23 0intro
99 6f4d00ee 2013-09-23 0intro static ulong
100 6f4d00ee 2013-09-23 0intro big(void *a, int n)
101 6f4d00ee 2013-09-23 0intro {
102 6f4d00ee 2013-09-23 0intro uchar *p;
103 6f4d00ee 2013-09-23 0intro ulong v;
104 6f4d00ee 2013-09-23 0intro int i;
105 6f4d00ee 2013-09-23 0intro
106 6f4d00ee 2013-09-23 0intro p = a;
107 6f4d00ee 2013-09-23 0intro v = 0;
108 6f4d00ee 2013-09-23 0intro for(i=0; i<n; i++)
109 6f4d00ee 2013-09-23 0intro v = (v<<8) | *p++;
110 6f4d00ee 2013-09-23 0intro return v;
111 6f4d00ee 2013-09-23 0intro }
112 6f4d00ee 2013-09-23 0intro
113 6f4d00ee 2013-09-23 0intro static ulong
114 6f4d00ee 2013-09-23 0intro little(void *a, int n)
115 6f4d00ee 2013-09-23 0intro {
116 6f4d00ee 2013-09-23 0intro uchar *p;
117 6f4d00ee 2013-09-23 0intro ulong v;
118 6f4d00ee 2013-09-23 0intro int i;
119 6f4d00ee 2013-09-23 0intro
120 6f4d00ee 2013-09-23 0intro p = a;
121 6f4d00ee 2013-09-23 0intro v = 0;
122 6f4d00ee 2013-09-23 0intro for(i=0; i<n; i++)
123 6f4d00ee 2013-09-23 0intro v |= (*p++<<(i*8));
124 6f4d00ee 2013-09-23 0intro return v;
125 6f4d00ee 2013-09-23 0intro }
126 6f4d00ee 2013-09-23 0intro
127 6f4d00ee 2013-09-23 0intro /* numbers in big or little endian. */
128 6f4d00ee 2013-09-23 0intro static int
129 6f4d00ee 2013-09-23 0intro BLfmt(Fmt *fmt)
130 6f4d00ee 2013-09-23 0intro {
131 6f4d00ee 2013-09-23 0intro ulong v;
132 6f4d00ee 2013-09-23 0intro uchar *p;
133 6f4d00ee 2013-09-23 0intro char buf[20];
134 6f4d00ee 2013-09-23 0intro
135 6f4d00ee 2013-09-23 0intro p = va_arg(fmt->args, uchar*);
136 6f4d00ee 2013-09-23 0intro
137 6f4d00ee 2013-09-23 0intro if(!(fmt->flags&FmtPrec)) {
138 6f4d00ee 2013-09-23 0intro fmtstrcpy(fmt, "*BL*");
139 6f4d00ee 2013-09-23 0intro return 0;
140 6f4d00ee 2013-09-23 0intro }
141 6f4d00ee 2013-09-23 0intro
142 6f4d00ee 2013-09-23 0intro if(fmt->r == 'B')
143 6f4d00ee 2013-09-23 0intro v = big(p, fmt->prec);
144 6f4d00ee 2013-09-23 0intro else
145 6f4d00ee 2013-09-23 0intro v = little(p, fmt->prec);
146 6f4d00ee 2013-09-23 0intro
147 6f4d00ee 2013-09-23 0intro sprint(buf, "0x%.*lux", fmt->prec*2, v);
148 6f4d00ee 2013-09-23 0intro fmt->flags &= ~FmtPrec;
149 6f4d00ee 2013-09-23 0intro fmtstrcpy(fmt, buf);
150 6f4d00ee 2013-09-23 0intro return 0;
151 6f4d00ee 2013-09-23 0intro }
152 6f4d00ee 2013-09-23 0intro
153 6f4d00ee 2013-09-23 0intro /* numbers in both little and big endian */
154 6f4d00ee 2013-09-23 0intro static int
155 6f4d00ee 2013-09-23 0intro Nfmt(Fmt *fmt)
156 6f4d00ee 2013-09-23 0intro {
157 6f4d00ee 2013-09-23 0intro char buf[100];
158 6f4d00ee 2013-09-23 0intro uchar *p;
159 6f4d00ee 2013-09-23 0intro
160 6f4d00ee 2013-09-23 0intro p = va_arg(fmt->args, uchar*);
161 6f4d00ee 2013-09-23 0intro
162 6f4d00ee 2013-09-23 0intro sprint(buf, "%.*L %.*B", fmt->prec, p, fmt->prec, p+fmt->prec);
163 6f4d00ee 2013-09-23 0intro fmt->flags &= ~FmtPrec;
164 6f4d00ee 2013-09-23 0intro fmtstrcpy(fmt, buf);
165 6f4d00ee 2013-09-23 0intro return 0;
166 6f4d00ee 2013-09-23 0intro }
167 6f4d00ee 2013-09-23 0intro
168 6f4d00ee 2013-09-23 0intro static int
169 6f4d00ee 2013-09-23 0intro asciiTfmt(Fmt *fmt)
170 6f4d00ee 2013-09-23 0intro {
171 6f4d00ee 2013-09-23 0intro char *p, buf[256];
172 6f4d00ee 2013-09-23 0intro int i;
173 6f4d00ee 2013-09-23 0intro
174 6f4d00ee 2013-09-23 0intro p = va_arg(fmt->args, char*);
175 6f4d00ee 2013-09-23 0intro for(i=0; i<fmt->prec; i++)
176 6f4d00ee 2013-09-23 0intro buf[i] = *p++;
177 6f4d00ee 2013-09-23 0intro buf[i] = '\0';
178 6f4d00ee 2013-09-23 0intro for(p=buf+strlen(buf); p>buf && p[-1]==' '; p--)
179 6f4d00ee 2013-09-23 0intro ;
180 6f4d00ee 2013-09-23 0intro p[0] = '\0';
181 6f4d00ee 2013-09-23 0intro fmt->flags &= ~FmtPrec;
182 6f4d00ee 2013-09-23 0intro fmtstrcpy(fmt, buf);
183 6f4d00ee 2013-09-23 0intro return 0;
184 6f4d00ee 2013-09-23 0intro }
185 6f4d00ee 2013-09-23 0intro
186 6f4d00ee 2013-09-23 0intro static void
187 6f4d00ee 2013-09-23 0intro ascii(void)
188 6f4d00ee 2013-09-23 0intro {
189 4b576658 2013-09-23 0intro fmtinstall('C', asciiTfmt);
190 6f4d00ee 2013-09-23 0intro }
191 6f4d00ee 2013-09-23 0intro
192 6f4d00ee 2013-09-23 0intro static void
193 6f4d00ee 2013-09-23 0intro getsect(uchar *buf, int n)
194 6f4d00ee 2013-09-23 0intro {
195 6f4d00ee 2013-09-23 0intro if(Bseek(b, n*2048, 0) != n*2048 || Bread(b, buf, 2048) != 2048)
196 6f4d00ee 2013-09-23 0intro {
197 6f4d00ee 2013-09-23 0intro abort();
198 6f4d00ee 2013-09-23 0intro sysfatal("reading block at %,d: %r", n*2048);
199 6f4d00ee 2013-09-23 0intro }
200 6f4d00ee 2013-09-23 0intro }
201 6f4d00ee 2013-09-23 0intro
202 6f4d00ee 2013-09-23 0intro static Header *h;
203 6f4d00ee 2013-09-23 0intro static int fd;
204 6f4d00ee 2013-09-23 0intro static char *file9660;
205 6f4d00ee 2013-09-23 0intro static int off9660;
206 6f4d00ee 2013-09-23 0intro static ulong startoff;
207 6f4d00ee 2013-09-23 0intro static ulong endoff;
208 6f4d00ee 2013-09-23 0intro static ulong fsoff;
209 6f4d00ee 2013-09-23 0intro static uchar root[2048];
210 6f4d00ee 2013-09-23 0intro static Voldesc *v;
211 6f4d00ee 2013-09-23 0intro static ulong iso9660start(Cdir*);
212 6f4d00ee 2013-09-23 0intro static void iso9660copydir(Fs*, File*, Cdir*);
213 6f4d00ee 2013-09-23 0intro static void iso9660copyfile(Fs*, File*, Cdir*);
214 6f4d00ee 2013-09-23 0intro
215 6f4d00ee 2013-09-23 0intro void
216 6f4d00ee 2013-09-23 0intro iso9660init(int xfd, Header *xh, char *xfile9660, int xoff9660)
217 6f4d00ee 2013-09-23 0intro {
218 6f4d00ee 2013-09-23 0intro uchar sect[2048], sect2[2048];
219 6f4d00ee 2013-09-23 0intro
220 6f4d00ee 2013-09-23 0intro fmtinstall('L', BLfmt);
221 6f4d00ee 2013-09-23 0intro fmtinstall('B', BLfmt);
222 6f4d00ee 2013-09-23 0intro fmtinstall('N', Nfmt);
223 6f4d00ee 2013-09-23 0intro fmtinstall('D', Dfmt);
224 6f4d00ee 2013-09-23 0intro
225 6f4d00ee 2013-09-23 0intro fd = xfd;
226 6f4d00ee 2013-09-23 0intro h = xh;
227 6f4d00ee 2013-09-23 0intro file9660 = xfile9660;
228 6f4d00ee 2013-09-23 0intro off9660 = xoff9660;
229 6f4d00ee 2013-09-23 0intro
230 6f4d00ee 2013-09-23 0intro if((b = Bopen(file9660, OREAD)) == nil)
231 4b576658 2013-09-23 0intro sysfatal("Bopen %s: %r", file9660);
232 6f4d00ee 2013-09-23 0intro
233 6f4d00ee 2013-09-23 0intro getsect(root, 16);
234 6f4d00ee 2013-09-23 0intro ascii();
235 6f4d00ee 2013-09-23 0intro
236 6f4d00ee 2013-09-23 0intro v = (Voldesc*)root;
237 b29ebaab 2013-10-23 0intro if(memcmp(v->magic, "\001CD001\001\000", 8) != 0)
238 4b576658 2013-09-23 0intro sysfatal("%s not a cd image", file9660);
239 6f4d00ee 2013-09-23 0intro
240 6f4d00ee 2013-09-23 0intro startoff = iso9660start((Cdir*)v->rootdir)*Blocksize;
241 6f4d00ee 2013-09-23 0intro endoff = little(v->volsize, 4); /* already in bytes */
242 6f4d00ee 2013-09-23 0intro
243 6f4d00ee 2013-09-23 0intro fsoff = off9660 + h->data*h->blockSize;
244 6f4d00ee 2013-09-23 0intro if(fsoff > startoff)
245 4b576658 2013-09-23 0intro sysfatal("fossil data starts after cd data");
246 6f4d00ee 2013-09-23 0intro if(off9660 + (vlong)h->end*h->blockSize < endoff)
247 4b576658 2013-09-23 0intro sysfatal("fossil data ends before cd data");
248 6f4d00ee 2013-09-23 0intro if(fsoff%h->blockSize)
249 4b576658 2013-09-23 0intro sysfatal("cd offset not a multiple of fossil block size");
250 6f4d00ee 2013-09-23 0intro
251 6f4d00ee 2013-09-23 0intro /* Read "same" block via CD image and via Fossil image */
252 6f4d00ee 2013-09-23 0intro getsect(sect, startoff/Blocksize);
253 6f4d00ee 2013-09-23 0intro if(seek(fd, startoff-off9660, 0) < 0)
254 4b576658 2013-09-23 0intro sysfatal("cannot seek to first data sector on cd via fossil");
255 6f4d00ee 2013-09-23 0intro fprint(2, "look for %lud at %lud\n", startoff, startoff-off9660);
256 6f4d00ee 2013-09-23 0intro if(readn(fd, sect2, Blocksize) != Blocksize)
257 4b576658 2013-09-23 0intro sysfatal("cannot read first data sector on cd via fossil");
258 6f4d00ee 2013-09-23 0intro if(memcmp(sect, sect2, Blocksize) != 0)
259 b29ebaab 2013-10-23 0intro sysfatal("iso9660 offset is a lie");
260 6f4d00ee 2013-09-23 0intro }
261 6f4d00ee 2013-09-23 0intro
262 6f4d00ee 2013-09-23 0intro void
263 6f4d00ee 2013-09-23 0intro iso9660labels(Disk *disk, uchar *buf, void (*write)(int, u32int))
264 6f4d00ee 2013-09-23 0intro {
265 6f4d00ee 2013-09-23 0intro ulong sb, eb, bn, lb, llb;
266 6f4d00ee 2013-09-23 0intro Label l;
267 6f4d00ee 2013-09-23 0intro int lpb;
268 6f4d00ee 2013-09-23 0intro uchar sect[Blocksize];
269 6f4d00ee 2013-09-23 0intro
270 6f4d00ee 2013-09-23 0intro if(!diskReadRaw(disk, PartData, (startoff-fsoff)/h->blockSize, buf))
271 4b576658 2013-09-23 0intro sysfatal("disk read failed: %r");
272 6f4d00ee 2013-09-23 0intro getsect(sect, startoff/Blocksize);
273 6f4d00ee 2013-09-23 0intro if(memcmp(buf, sect, Blocksize) != 0)
274 4b576658 2013-09-23 0intro sysfatal("fsoff is wrong");
275 6f4d00ee 2013-09-23 0intro
276 6f4d00ee 2013-09-23 0intro sb = (startoff-fsoff)/h->blockSize;
277 6f4d00ee 2013-09-23 0intro eb = (endoff-fsoff+h->blockSize-1)/h->blockSize;
278 6f4d00ee 2013-09-23 0intro
279 6f4d00ee 2013-09-23 0intro lpb = h->blockSize/LabelSize;
280 6f4d00ee 2013-09-23 0intro
281 6f4d00ee 2013-09-23 0intro /* for each reserved block, mark label */
282 6f4d00ee 2013-09-23 0intro llb = ~0;
283 6f4d00ee 2013-09-23 0intro l.type = BtData;
284 6f4d00ee 2013-09-23 0intro l.state = BsAlloc;
285 6f4d00ee 2013-09-23 0intro l.tag = Tag;
286 6f4d00ee 2013-09-23 0intro l.epoch = 1;
287 6f4d00ee 2013-09-23 0intro l.epochClose = ~(u32int)0;
288 6f4d00ee 2013-09-23 0intro for(bn=sb; bn<eb; bn++){
289 6f4d00ee 2013-09-23 0intro lb = bn/lpb;
290 6f4d00ee 2013-09-23 0intro if(lb != llb){
291 6f4d00ee 2013-09-23 0intro if(llb != ~0)
292 6f4d00ee 2013-09-23 0intro (*write)(PartLabel, llb);
293 6f4d00ee 2013-09-23 0intro memset(buf, 0, h->blockSize);
294 6f4d00ee 2013-09-23 0intro }
295 6f4d00ee 2013-09-23 0intro llb = lb;
296 6f4d00ee 2013-09-23 0intro labelPack(&l, buf, bn%lpb);
297 6f4d00ee 2013-09-23 0intro }
298 6f4d00ee 2013-09-23 0intro if(llb != ~0)
299 6f4d00ee 2013-09-23 0intro (*write)(PartLabel, llb);
300 6f4d00ee 2013-09-23 0intro }
301 6f4d00ee 2013-09-23 0intro
302 6f4d00ee 2013-09-23 0intro void
303 6f4d00ee 2013-09-23 0intro iso9660copy(Fs *fs)
304 6f4d00ee 2013-09-23 0intro {
305 6f4d00ee 2013-09-23 0intro File *root;
306 6f4d00ee 2013-09-23 0intro
307 6f4d00ee 2013-09-23 0intro root = fileOpen(fs, "/active");
308 6f4d00ee 2013-09-23 0intro iso9660copydir(fs, root, (Cdir*)v->rootdir);
309 6f4d00ee 2013-09-23 0intro fileDecRef(root);
310 4b576658 2013-09-23 0intro runlock(&fs->elk);
311 6f4d00ee 2013-09-23 0intro if(!fsSnapshot(fs, nil, nil, 0))
312 4b576658 2013-09-23 0intro sysfatal("snapshot failed: %r");
313 4b576658 2013-09-23 0intro rlock(&fs->elk);
314 6f4d00ee 2013-09-23 0intro }
315 6f4d00ee 2013-09-23 0intro
316 6f4d00ee 2013-09-23 0intro /*
317 6f4d00ee 2013-09-23 0intro * The first block used is the first data block of the leftmost file in the tree.
318 6f4d00ee 2013-09-23 0intro * (Just an artifact of how mk9660 works.)
319 6f4d00ee 2013-09-23 0intro */
320 6f4d00ee 2013-09-23 0intro static ulong
321 6f4d00ee 2013-09-23 0intro iso9660start(Cdir *c)
322 6f4d00ee 2013-09-23 0intro {
323 6f4d00ee 2013-09-23 0intro uchar sect[Blocksize];
324 6f4d00ee 2013-09-23 0intro
325 6f4d00ee 2013-09-23 0intro while(c->flags&2){
326 6f4d00ee 2013-09-23 0intro getsect(sect, little(c->dloc, 4));
327 6f4d00ee 2013-09-23 0intro c = (Cdir*)sect;
328 6f4d00ee 2013-09-23 0intro c = (Cdir*)((uchar*)c+c->len); /* skip dot */
329 6f4d00ee 2013-09-23 0intro c = (Cdir*)((uchar*)c+c->len); /* skip dotdot */
330 6f4d00ee 2013-09-23 0intro /* oops: might happen if leftmost directory is empty or leftmost file is zero length! */
331 6f4d00ee 2013-09-23 0intro if(little(c->dloc, 4) == 0)
332 fa325e9b 2020-01-10 cross sysfatal("error parsing cd image or unfortunate cd image");
333 6f4d00ee 2013-09-23 0intro }
334 6f4d00ee 2013-09-23 0intro return little(c->dloc, 4);
335 6f4d00ee 2013-09-23 0intro }
336 6f4d00ee 2013-09-23 0intro
337 6f4d00ee 2013-09-23 0intro static void
338 6f4d00ee 2013-09-23 0intro iso9660copydir(Fs *fs, File *dir, Cdir *cd)
339 6f4d00ee 2013-09-23 0intro {
340 6f4d00ee 2013-09-23 0intro ulong off, end, len;
341 6f4d00ee 2013-09-23 0intro uchar sect[Blocksize], *esect, *p;
342 6f4d00ee 2013-09-23 0intro Cdir *c;
343 6f4d00ee 2013-09-23 0intro
344 6f4d00ee 2013-09-23 0intro len = little(cd->dlen, 4);
345 6f4d00ee 2013-09-23 0intro off = little(cd->dloc, 4)*Blocksize;
346 6f4d00ee 2013-09-23 0intro end = off+len;
347 6f4d00ee 2013-09-23 0intro esect = sect+Blocksize;
348 6f4d00ee 2013-09-23 0intro
349 6f4d00ee 2013-09-23 0intro for(; off<end; off+=Blocksize){
350 6f4d00ee 2013-09-23 0intro getsect(sect, off/Blocksize);
351 6f4d00ee 2013-09-23 0intro p = sect;
352 6f4d00ee 2013-09-23 0intro while(p < esect){
353 6f4d00ee 2013-09-23 0intro c = (Cdir*)p;
354 6f4d00ee 2013-09-23 0intro if(c->len <= 0)
355 6f4d00ee 2013-09-23 0intro break;
356 6f4d00ee 2013-09-23 0intro if(c->namelen!=1 || c->name[0]>1)
357 6f4d00ee 2013-09-23 0intro iso9660copyfile(fs, dir, c);
358 6f4d00ee 2013-09-23 0intro p += c->len;
359 6f4d00ee 2013-09-23 0intro }
360 6f4d00ee 2013-09-23 0intro }
361 6f4d00ee 2013-09-23 0intro }
362 6f4d00ee 2013-09-23 0intro
363 6f4d00ee 2013-09-23 0intro static char*
364 6f4d00ee 2013-09-23 0intro getname(uchar **pp)
365 6f4d00ee 2013-09-23 0intro {
366 6f4d00ee 2013-09-23 0intro uchar *p;
367 6f4d00ee 2013-09-23 0intro int l;
368 6f4d00ee 2013-09-23 0intro
369 6f4d00ee 2013-09-23 0intro p = *pp;
370 6f4d00ee 2013-09-23 0intro l = *p;
371 6f4d00ee 2013-09-23 0intro *pp = p+1+l;
372 6f4d00ee 2013-09-23 0intro if(l == 0)
373 6f4d00ee 2013-09-23 0intro return "";
374 6f4d00ee 2013-09-23 0intro memmove(p, p+1, l);
375 6f4d00ee 2013-09-23 0intro p[l] = 0;
376 6f4d00ee 2013-09-23 0intro return (char*)p;
377 6f4d00ee 2013-09-23 0intro }
378 6f4d00ee 2013-09-23 0intro
379 6f4d00ee 2013-09-23 0intro static char*
380 6f4d00ee 2013-09-23 0intro getcname(Cdir *c)
381 6f4d00ee 2013-09-23 0intro {
382 6f4d00ee 2013-09-23 0intro uchar *up;
383 6f4d00ee 2013-09-23 0intro char *p, *q;
384 6f4d00ee 2013-09-23 0intro
385 6f4d00ee 2013-09-23 0intro up = &c->namelen;
386 6f4d00ee 2013-09-23 0intro p = getname(&up);
387 6f4d00ee 2013-09-23 0intro for(q=p; *q; q++)
388 6f4d00ee 2013-09-23 0intro *q = tolower(*q);
389 6f4d00ee 2013-09-23 0intro return p;
390 6f4d00ee 2013-09-23 0intro }
391 6f4d00ee 2013-09-23 0intro
392 6f4d00ee 2013-09-23 0intro static char
393 6f4d00ee 2013-09-23 0intro dmsize[12] =
394 6f4d00ee 2013-09-23 0intro {
395 6f4d00ee 2013-09-23 0intro 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
396 6f4d00ee 2013-09-23 0intro };
397 6f4d00ee 2013-09-23 0intro
398 6f4d00ee 2013-09-23 0intro static ulong
399 6f4d00ee 2013-09-23 0intro getcdate(uchar *p) /* yMdhmsz */
400 6f4d00ee 2013-09-23 0intro {
401 6f4d00ee 2013-09-23 0intro Tm tm;
402 6f4d00ee 2013-09-23 0intro int y, M, d, h, m, s, tz;
403 6f4d00ee 2013-09-23 0intro
404 6f4d00ee 2013-09-23 0intro y=p[0]; M=p[1]; d=p[2];
405 6f4d00ee 2013-09-23 0intro h=p[3]; m=p[4]; s=p[5]; tz=p[6];
406 6f4d00ee 2013-09-23 0intro USED(tz);
407 6f4d00ee 2013-09-23 0intro if (y < 70)
408 6f4d00ee 2013-09-23 0intro return 0;
409 6f4d00ee 2013-09-23 0intro if (M < 1 || M > 12)
410 6f4d00ee 2013-09-23 0intro return 0;
411 6f4d00ee 2013-09-23 0intro if (d < 1 || d > dmsize[M-1])
412 6f4d00ee 2013-09-23 0intro return 0;
413 6f4d00ee 2013-09-23 0intro if (h > 23)
414 6f4d00ee 2013-09-23 0intro return 0;
415 6f4d00ee 2013-09-23 0intro if (m > 59)
416 6f4d00ee 2013-09-23 0intro return 0;
417 6f4d00ee 2013-09-23 0intro if (s > 59)
418 6f4d00ee 2013-09-23 0intro return 0;
419 6f4d00ee 2013-09-23 0intro
420 6f4d00ee 2013-09-23 0intro memset(&tm, 0, sizeof tm);
421 6f4d00ee 2013-09-23 0intro tm.sec = s;
422 6f4d00ee 2013-09-23 0intro tm.min = m;
423 6f4d00ee 2013-09-23 0intro tm.hour = h;
424 6f4d00ee 2013-09-23 0intro tm.mday = d;
425 6f4d00ee 2013-09-23 0intro tm.mon = M-1;
426 6f4d00ee 2013-09-23 0intro tm.year = 1900+y;
427 6f4d00ee 2013-09-23 0intro tm.zone[0] = 0;
428 6f4d00ee 2013-09-23 0intro return tm2sec(&tm);
429 6f4d00ee 2013-09-23 0intro }
430 6f4d00ee 2013-09-23 0intro
431 6f4d00ee 2013-09-23 0intro static int ind;
432 6f4d00ee 2013-09-23 0intro
433 6f4d00ee 2013-09-23 0intro static void
434 6f4d00ee 2013-09-23 0intro iso9660copyfile(Fs *fs, File *dir, Cdir *c)
435 6f4d00ee 2013-09-23 0intro {
436 6f4d00ee 2013-09-23 0intro Dir d;
437 6f4d00ee 2013-09-23 0intro DirEntry de;
438 6f4d00ee 2013-09-23 0intro int sysl;
439 6f4d00ee 2013-09-23 0intro uchar score[VtScoreSize];
440 6f4d00ee 2013-09-23 0intro ulong off, foff, len, mode;
441 6f4d00ee 2013-09-23 0intro uchar *p;
442 6f4d00ee 2013-09-23 0intro File *f;
443 6f4d00ee 2013-09-23 0intro
444 6f4d00ee 2013-09-23 0intro ind++;
445 6f4d00ee 2013-09-23 0intro memset(&d, 0, sizeof d);
446 6f4d00ee 2013-09-23 0intro p = c->name + c->namelen;
447 6f4d00ee 2013-09-23 0intro if(((uintptr)p) & 1)
448 6f4d00ee 2013-09-23 0intro p++;
449 6f4d00ee 2013-09-23 0intro sysl = (uchar*)c + c->len - p;
450 6f4d00ee 2013-09-23 0intro if(sysl <= 0)
451 4b576658 2013-09-23 0intro sysfatal("missing plan9 directory entry on %d/%d/%.*s", c->namelen, c->name[0], c->namelen, c->name);
452 6f4d00ee 2013-09-23 0intro d.name = getname(&p);
453 6f4d00ee 2013-09-23 0intro d.uid = getname(&p);
454 6f4d00ee 2013-09-23 0intro d.gid = getname(&p);
455 6f4d00ee 2013-09-23 0intro if((uintptr)p & 1)
456 6f4d00ee 2013-09-23 0intro p++;
457 6f4d00ee 2013-09-23 0intro d.mode = little(p, 4);
458 6f4d00ee 2013-09-23 0intro if(d.name[0] == 0)
459 6f4d00ee 2013-09-23 0intro d.name = getcname(c);
460 6f4d00ee 2013-09-23 0intro d.mtime = getcdate(c->date);
461 6f4d00ee 2013-09-23 0intro d.atime = d.mtime;
462 6f4d00ee 2013-09-23 0intro
463 6f4d00ee 2013-09-23 0intro if(d.mode&DMDIR) print("%*scopy %s %s %s %luo\n", ind*2, "", d.name, d.uid, d.gid, d.mode);
464 6f4d00ee 2013-09-23 0intro
465 6f4d00ee 2013-09-23 0intro mode = d.mode&0777;
466 6f4d00ee 2013-09-23 0intro if(d.mode&DMDIR)
467 6f4d00ee 2013-09-23 0intro mode |= ModeDir;
468 6f4d00ee 2013-09-23 0intro if((f = fileCreate(dir, d.name, mode, d.uid)) == nil)
469 4b576658 2013-09-23 0intro sysfatal("could not create file '%s': %r", d.name);
470 6f4d00ee 2013-09-23 0intro if(d.mode&DMDIR)
471 6f4d00ee 2013-09-23 0intro iso9660copydir(fs, f, c);
472 6f4d00ee 2013-09-23 0intro else{
473 6f4d00ee 2013-09-23 0intro len = little(c->dlen, 4);
474 6f4d00ee 2013-09-23 0intro off = little(c->dloc, 4)*Blocksize;
475 6f4d00ee 2013-09-23 0intro for(foff=0; foff<len; foff+=h->blockSize){
476 6f4d00ee 2013-09-23 0intro localToGlobal((off+foff-fsoff)/h->blockSize, score);
477 6f4d00ee 2013-09-23 0intro if(!fileMapBlock(f, foff/h->blockSize, score, Tag))
478 4b576658 2013-09-23 0intro sysfatal("fileMapBlock: %r");
479 6f4d00ee 2013-09-23 0intro }
480 6f4d00ee 2013-09-23 0intro if(!fileSetSize(f, len))
481 4b576658 2013-09-23 0intro sysfatal("fileSetSize: %r");
482 6f4d00ee 2013-09-23 0intro }
483 6f4d00ee 2013-09-23 0intro if(!fileGetDir(f, &de))
484 4b576658 2013-09-23 0intro sysfatal("fileGetDir: %r");
485 6f4d00ee 2013-09-23 0intro de.uid = d.uid;
486 6f4d00ee 2013-09-23 0intro de.gid = d.gid;
487 6f4d00ee 2013-09-23 0intro de.mtime = d.mtime;
488 6f4d00ee 2013-09-23 0intro de.atime = d.atime;
489 6f4d00ee 2013-09-23 0intro de.mode = d.mode&0777;
490 6f4d00ee 2013-09-23 0intro if(!fileSetDir(f, &de, "sys"))
491 4b576658 2013-09-23 0intro sysfatal("fileSetDir: %r");
492 6f4d00ee 2013-09-23 0intro fileDecRef(f);
493 6f4d00ee 2013-09-23 0intro ind--;
494 6f4d00ee 2013-09-23 0intro }