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 /*
9 7285a491 2004-06-17 devnull * Add the requisite path tables to the CD image.
10 7285a491 2004-06-17 devnull * They get put on the end once everything else is done.
11 7285a491 2004-06-17 devnull * We use the path table itself as a queue in the breadth-first
12 fa325e9b 2020-01-10 cross * traversal of the tree.
13 7285a491 2004-06-17 devnull *
14 7285a491 2004-06-17 devnull * The only problem with this is that the path table does not
15 7285a491 2004-06-17 devnull * store the lengths of the directories. So we keep an explicit
16 7285a491 2004-06-17 devnull * map in an array in memory.
17 7285a491 2004-06-17 devnull */
18 7285a491 2004-06-17 devnull
19 7285a491 2004-06-17 devnull enum {
20 7285a491 2004-06-17 devnull Big,
21 7285a491 2004-06-17 devnull Little
22 7285a491 2004-06-17 devnull };
23 7285a491 2004-06-17 devnull
24 7285a491 2004-06-17 devnull static void
25 7285a491 2004-06-17 devnull Crdpath(Cdimg *cd, Cpath *p)
26 7285a491 2004-06-17 devnull {
27 7285a491 2004-06-17 devnull p->namelen = Cgetc(cd);
28 7285a491 2004-06-17 devnull if(p->namelen == 0) {
29 7285a491 2004-06-17 devnull Crseek(cd, (Croffset(cd)+Blocksize-1)/Blocksize * Blocksize);
30 7285a491 2004-06-17 devnull p->namelen = Cgetc(cd);
31 7285a491 2004-06-17 devnull assert(p->namelen != 0);
32 7285a491 2004-06-17 devnull }
33 7285a491 2004-06-17 devnull
34 7285a491 2004-06-17 devnull p->xlen = Cgetc(cd);
35 7285a491 2004-06-17 devnull assert(p->xlen == 0); /* sanity, might not be true if we start using the extended fields */
36 7285a491 2004-06-17 devnull
37 7285a491 2004-06-17 devnull Cread(cd, p->dloc, 4);
38 7285a491 2004-06-17 devnull Cread(cd, p->parent, 2);
39 7285a491 2004-06-17 devnull p->name[0] = '\0';
40 7285a491 2004-06-17 devnull Crseek(cd, Croffset(cd)+p->namelen+p->xlen+(p->namelen&1)); /* skip name, ext data */
41 7285a491 2004-06-17 devnull }
42 7285a491 2004-06-17 devnull
43 7285a491 2004-06-17 devnull static void
44 7285a491 2004-06-17 devnull writepath(Cdimg *cd, Cdir *c, int parent, int size)
45 7285a491 2004-06-17 devnull {
46 7285a491 2004-06-17 devnull /*
47 7285a491 2004-06-17 devnull DO NOT UNCOMMENT THIS CODE.
48 7285a491 2004-06-17 devnull This commented-out code is here only so that no one comes
49 7285a491 2004-06-17 devnull along and adds it later.
50 7285a491 2004-06-17 devnull
51 7285a491 2004-06-17 devnull The ISO 9660 spec is silent about whether path table entries
52 7285a491 2004-06-17 devnull need to be padded so that they never cross block boundaries.
53 7285a491 2004-06-17 devnull It would be reasonable to assume that they are like every other
54 7285a491 2004-06-17 devnull data structure in the bloody spec; this code pads them out.
55 7285a491 2004-06-17 devnull
56 7285a491 2004-06-17 devnull Empirically, though, they're NOT padded. Windows NT and
57 7285a491 2004-06-17 devnull derivatives are the only known current operating systems
58 7285a491 2004-06-17 devnull that actually read these things.
59 7285a491 2004-06-17 devnull
60 7285a491 2004-06-17 devnull int l;
61 7285a491 2004-06-17 devnull
62 7285a491 2004-06-17 devnull l = 1+1+4+2+c->namelen;
63 7285a491 2004-06-17 devnull if(Cwoffset(cd)/Blocksize != (Cwoffset(cd)+l)/Blocksize)
64 7285a491 2004-06-17 devnull Cpadblock(cd);
65 7285a491 2004-06-17 devnull */
66 7285a491 2004-06-17 devnull Cputc(cd, c->namelen);
67 7285a491 2004-06-17 devnull Cputc(cd, 0);
68 7285a491 2004-06-17 devnull Cwrite(cd, c->dloc + (size==Little ? 0 : 4), 4);
69 7285a491 2004-06-17 devnull (size==Little ? Cputnl : Cputnm)(cd, parent, 2);
70 7285a491 2004-06-17 devnull Cwrite(cd, c->name, c->namelen);
71 7285a491 2004-06-17 devnull if(c->namelen & 1)
72 7285a491 2004-06-17 devnull Cputc(cd, 0);
73 7285a491 2004-06-17 devnull }
74 7285a491 2004-06-17 devnull
75 7285a491 2004-06-17 devnull static ulong*
76 7285a491 2004-06-17 devnull addlength(ulong *a, ulong x, int n)
77 7285a491 2004-06-17 devnull {
78 7285a491 2004-06-17 devnull if(n%128==0)
79 7285a491 2004-06-17 devnull a = erealloc(a, (n+128)*sizeof a[0]);
80 7285a491 2004-06-17 devnull a[n] = x;
81 7285a491 2004-06-17 devnull return a;
82 7285a491 2004-06-17 devnull }
83 7285a491 2004-06-17 devnull
84 7285a491 2004-06-17 devnull static ulong
85 7285a491 2004-06-17 devnull writepathtable(Cdimg *cd, ulong vdblock, int size)
86 7285a491 2004-06-17 devnull {
87 7285a491 2004-06-17 devnull int rp, wp;
88 7285a491 2004-06-17 devnull uchar buf[Blocksize];
89 7285a491 2004-06-17 devnull ulong bk, end, i, *len, n, rdoff, start;
90 7285a491 2004-06-17 devnull Cdir *c;
91 7285a491 2004-06-17 devnull Cpath p;
92 7285a491 2004-06-17 devnull
93 7285a491 2004-06-17 devnull Creadblock(cd, buf, vdblock, Blocksize);
94 7285a491 2004-06-17 devnull c = (Cdir*)(buf+offsetof(Cvoldesc, rootdir[0]));
95 7285a491 2004-06-17 devnull
96 7285a491 2004-06-17 devnull rp = 0;
97 7285a491 2004-06-17 devnull wp = 0;
98 7285a491 2004-06-17 devnull len = nil;
99 7285a491 2004-06-17 devnull start = cd->nextblock*Blocksize;
100 7285a491 2004-06-17 devnull Cwseek(cd, start);
101 7285a491 2004-06-17 devnull Crseek(cd, start);
102 7285a491 2004-06-17 devnull writepath(cd, c, 1, size);
103 7285a491 2004-06-17 devnull len = addlength(len, little(c->dlen, 4), wp);
104 7285a491 2004-06-17 devnull wp++;
105 7285a491 2004-06-17 devnull
106 7285a491 2004-06-17 devnull while(rp < wp) {
107 7285a491 2004-06-17 devnull Crdpath(cd, &p);
108 7285a491 2004-06-17 devnull n = (len[rp]+Blocksize-1)/Blocksize;
109 7285a491 2004-06-17 devnull rp++;
110 7285a491 2004-06-17 devnull bk = (size==Big ? big : little)(p.dloc, 4);
111 7285a491 2004-06-17 devnull rdoff = Croffset(cd);
112 7285a491 2004-06-17 devnull for(i=0; i<n; i++) {
113 7285a491 2004-06-17 devnull Creadblock(cd, buf, bk+i, Blocksize);
114 7285a491 2004-06-17 devnull c = (Cdir*)buf;
115 7285a491 2004-06-17 devnull if(i != 0 && c->namelen == 1 && c->name[0] == '\0') /* hit another directory; stop */
116 7285a491 2004-06-17 devnull break;
117 7285a491 2004-06-17 devnull while(c->len && c->namelen && (uchar*)c+c->len < buf+Blocksize) {
118 7285a491 2004-06-17 devnull if((c->flags & 0x02) && (c->namelen > 1 || c->name[0] > '\001')) { /* directory */
119 7285a491 2004-06-17 devnull writepath(cd, c, rp, size);
120 7285a491 2004-06-17 devnull len = addlength(len, little(c->dlen, 4), wp);
121 7285a491 2004-06-17 devnull wp++;
122 7285a491 2004-06-17 devnull }
123 7285a491 2004-06-17 devnull c = (Cdir*)((uchar*)c+c->len);
124 7285a491 2004-06-17 devnull }
125 7285a491 2004-06-17 devnull }
126 7285a491 2004-06-17 devnull Crseek(cd, rdoff);
127 7285a491 2004-06-17 devnull }
128 7285a491 2004-06-17 devnull end = Cwoffset(cd);
129 7285a491 2004-06-17 devnull Cpadblock(cd);
130 7285a491 2004-06-17 devnull return end-start;
131 7285a491 2004-06-17 devnull }
132 7285a491 2004-06-17 devnull
133 7285a491 2004-06-17 devnull
134 7285a491 2004-06-17 devnull static void
135 7285a491 2004-06-17 devnull writepathtablepair(Cdimg *cd, ulong vdblock)
136 7285a491 2004-06-17 devnull {
137 7285a491 2004-06-17 devnull ulong bloc, lloc, sz, sz2;
138 7285a491 2004-06-17 devnull
139 7285a491 2004-06-17 devnull lloc = cd->nextblock;
140 7285a491 2004-06-17 devnull sz = writepathtable(cd, vdblock, Little);
141 7285a491 2004-06-17 devnull bloc = cd->nextblock;
142 7285a491 2004-06-17 devnull sz2 = writepathtable(cd, vdblock, Big);
143 7285a491 2004-06-17 devnull assert(sz == sz2);
144 7285a491 2004-06-17 devnull setpathtable(cd, vdblock, sz, lloc, bloc);
145 7285a491 2004-06-17 devnull }
146 7285a491 2004-06-17 devnull
147 7285a491 2004-06-17 devnull void
148 7285a491 2004-06-17 devnull writepathtables(Cdimg *cd)
149 7285a491 2004-06-17 devnull {
150 7285a491 2004-06-17 devnull cd->pathblock = cd->nextblock;
151 7285a491 2004-06-17 devnull
152 7285a491 2004-06-17 devnull writepathtablepair(cd, cd->iso9660pvd);
153 7285a491 2004-06-17 devnull if(cd->flags & CDjoliet)
154 7285a491 2004-06-17 devnull writepathtablepair(cd, cd->jolietsvd);
155 7285a491 2004-06-17 devnull }