Blame


1 7285a491 2004-06-17 devnull /*
2 7285a491 2004-06-17 devnull * To understand this code, see Rock Ridge Interchange Protocol
3 7285a491 2004-06-17 devnull * standard 1.12 and System Use Sharing Protocol version 1.12
4 7285a491 2004-06-17 devnull * (search for rrip112.ps and susp112.ps on the web).
5 7285a491 2004-06-17 devnull *
6 7285a491 2004-06-17 devnull * Even better, go read something else.
7 7285a491 2004-06-17 devnull */
8 7285a491 2004-06-17 devnull
9 7285a491 2004-06-17 devnull #include <u.h>
10 7285a491 2004-06-17 devnull #include <libc.h>
11 7285a491 2004-06-17 devnull #include <bio.h>
12 7285a491 2004-06-17 devnull #include <libsec.h>
13 7285a491 2004-06-17 devnull #include "iso9660.h"
14 7285a491 2004-06-17 devnull
15 7285a491 2004-06-17 devnull static long mode(Direc*, int);
16 7285a491 2004-06-17 devnull static long nlink(Direc*);
17 7285a491 2004-06-17 devnull static ulong suspdirflags(Direc*, int);
18 7285a491 2004-06-17 devnull static ulong CputsuspCE(Cdimg *cd, ulong offset);
19 7285a491 2004-06-17 devnull static int CputsuspER(Cdimg*, int);
20 7285a491 2004-06-17 devnull static int CputsuspRR(Cdimg*, int, int);
21 7285a491 2004-06-17 devnull static int CputsuspSP(Cdimg*, int);
22 cbeb0b26 2006-04-01 devnull /*static int CputsuspST(Cdimg*, int); */
23 7285a491 2004-06-17 devnull static int Cputrripname(Cdimg*, char*, int, char*, int);
24 7285a491 2004-06-17 devnull static int CputrripSL(Cdimg*, int, int, char*, int);
25 7285a491 2004-06-17 devnull static int CputrripPX(Cdimg*, Direc*, int, int);
26 7285a491 2004-06-17 devnull static int CputrripTF(Cdimg*, Direc*, int, int);
27 7285a491 2004-06-17 devnull
28 7285a491 2004-06-17 devnull /*
29 7285a491 2004-06-17 devnull * Patch the length field in a CE record.
30 7285a491 2004-06-17 devnull */
31 7285a491 2004-06-17 devnull static void
32 7285a491 2004-06-17 devnull setcelen(Cdimg *cd, ulong woffset, ulong len)
33 7285a491 2004-06-17 devnull {
34 7285a491 2004-06-17 devnull ulong o;
35 7285a491 2004-06-17 devnull
36 7285a491 2004-06-17 devnull o = Cwoffset(cd);
37 7285a491 2004-06-17 devnull Cwseek(cd, woffset);
38 7285a491 2004-06-17 devnull Cputn(cd, len, 4);
39 7285a491 2004-06-17 devnull Cwseek(cd, o);
40 7285a491 2004-06-17 devnull }
41 7285a491 2004-06-17 devnull
42 7285a491 2004-06-17 devnull /*
43 7285a491 2004-06-17 devnull * Rock Ridge data is put into little blockettes, which can be
44 7285a491 2004-06-17 devnull * at most 256 bytes including a one-byte length. Some number
45 7285a491 2004-06-17 devnull * of blockettes get packed together into a normal 2048-byte block.
46 7285a491 2004-06-17 devnull * Blockettes cannot cross block boundaries.
47 7285a491 2004-06-17 devnull *
48 7285a491 2004-06-17 devnull * A Cbuf is a blockette buffer. Len contains
49 7285a491 2004-06-17 devnull * the length of the buffer written so far, and we can
50 7285a491 2004-06-17 devnull * write up to 254-28.
51 7285a491 2004-06-17 devnull *
52 7285a491 2004-06-17 devnull * We only have one active Cbuf at a time; cdimg.rrcontin is the byte
53 7285a491 2004-06-17 devnull * offset of the beginning of that Cbuf.
54 7285a491 2004-06-17 devnull *
55 7285a491 2004-06-17 devnull * The blockette can be at most 255 bytes. The last 28
56 7285a491 2004-06-17 devnull * will be (in the worst case) a CE record pointing at
57 7285a491 2004-06-17 devnull * a new blockette. If we do write 255 bytes though,
58 7285a491 2004-06-17 devnull * we'll try to pad it out to be even, and overflow.
59 7285a491 2004-06-17 devnull * So the maximum is 254-28.
60 7285a491 2004-06-17 devnull *
61 7285a491 2004-06-17 devnull * Ceoffset contains the offset to be used with setcelen
62 7285a491 2004-06-17 devnull * to patch the CE pointing at the Cbuf once we know how
63 7285a491 2004-06-17 devnull * long the Cbuf is.
64 7285a491 2004-06-17 devnull */
65 7285a491 2004-06-17 devnull typedef struct Cbuf Cbuf;
66 7285a491 2004-06-17 devnull struct Cbuf {
67 7285a491 2004-06-17 devnull int len; /* written so far, of 254-28 */
68 7285a491 2004-06-17 devnull ulong ceoffset;
69 7285a491 2004-06-17 devnull };
70 7285a491 2004-06-17 devnull
71 7285a491 2004-06-17 devnull static int
72 7285a491 2004-06-17 devnull freespace(Cbuf *cp)
73 7285a491 2004-06-17 devnull {
74 7285a491 2004-06-17 devnull return (254-28) - cp->len;
75 7285a491 2004-06-17 devnull }
76 7285a491 2004-06-17 devnull
77 7285a491 2004-06-17 devnull static Cbuf*
78 7285a491 2004-06-17 devnull ensurespace(Cdimg *cd, int n, Cbuf *co, Cbuf *cn, int dowrite)
79 7285a491 2004-06-17 devnull {
80 7285a491 2004-06-17 devnull ulong end;
81 7285a491 2004-06-17 devnull
82 7285a491 2004-06-17 devnull if(co->len+n <= 254-28) {
83 7285a491 2004-06-17 devnull co->len += n;
84 7285a491 2004-06-17 devnull return co;
85 7285a491 2004-06-17 devnull }
86 7285a491 2004-06-17 devnull
87 7285a491 2004-06-17 devnull co->len += 28;
88 7285a491 2004-06-17 devnull assert(co->len <= 254);
89 7285a491 2004-06-17 devnull
90 7285a491 2004-06-17 devnull if(dowrite == 0) {
91 7285a491 2004-06-17 devnull cn->len = n;
92 7285a491 2004-06-17 devnull return cn;
93 7285a491 2004-06-17 devnull }
94 7285a491 2004-06-17 devnull
95 7285a491 2004-06-17 devnull /*
96 7285a491 2004-06-17 devnull * the current blockette is full; update cd->rrcontin and then
97 7285a491 2004-06-17 devnull * write a CE record to finish it. Unfortunately we need to
98 7285a491 2004-06-17 devnull * figure out which block will be next before we write the CE.
99 7285a491 2004-06-17 devnull */
100 7285a491 2004-06-17 devnull end = Cwoffset(cd)+28;
101 7285a491 2004-06-17 devnull
102 7285a491 2004-06-17 devnull /*
103 7285a491 2004-06-17 devnull * if we're in a continuation blockette, update rrcontin.
104 7285a491 2004-06-17 devnull * also, write our length into the field of the CE record
105 7285a491 2004-06-17 devnull * that points at us.
106 7285a491 2004-06-17 devnull */
107 7285a491 2004-06-17 devnull if(cd->rrcontin+co->len == end) {
108 7285a491 2004-06-17 devnull assert(cd->rrcontin != 0);
109 7285a491 2004-06-17 devnull assert(co == cn);
110 7285a491 2004-06-17 devnull cd->rrcontin += co->len;
111 7285a491 2004-06-17 devnull setcelen(cd, co->ceoffset, co->len);
112 7285a491 2004-06-17 devnull } else
113 7285a491 2004-06-17 devnull assert(co != cn);
114 7285a491 2004-06-17 devnull
115 7285a491 2004-06-17 devnull /*
116 7285a491 2004-06-17 devnull * if the current continuation block can't fit another
117 7285a491 2004-06-17 devnull * blockette, then start a new continuation block.
118 7285a491 2004-06-17 devnull * rrcontin = 0 (mod Blocksize) means we just finished
119 7285a491 2004-06-17 devnull * one, not that we've just started one.
120 7285a491 2004-06-17 devnull */
121 7285a491 2004-06-17 devnull if(cd->rrcontin%Blocksize == 0
122 7285a491 2004-06-17 devnull || cd->rrcontin/Blocksize != (cd->rrcontin+256)/Blocksize) {
123 7285a491 2004-06-17 devnull cd->rrcontin = cd->nextblock*Blocksize;
124 7285a491 2004-06-17 devnull cd->nextblock++;
125 7285a491 2004-06-17 devnull }
126 7285a491 2004-06-17 devnull
127 7285a491 2004-06-17 devnull cn->ceoffset = CputsuspCE(cd, cd->rrcontin);
128 7285a491 2004-06-17 devnull
129 7285a491 2004-06-17 devnull assert(Cwoffset(cd) == end);
130 7285a491 2004-06-17 devnull
131 7285a491 2004-06-17 devnull cn->len = n;
132 7285a491 2004-06-17 devnull Cwseek(cd, cd->rrcontin);
133 7285a491 2004-06-17 devnull assert(cd->rrcontin != 0);
134 7285a491 2004-06-17 devnull
135 7285a491 2004-06-17 devnull return cn;
136 7285a491 2004-06-17 devnull }
137 7285a491 2004-06-17 devnull
138 7285a491 2004-06-17 devnull /*
139 7285a491 2004-06-17 devnull * Put down the name, but we might need to break it
140 7285a491 2004-06-17 devnull * into chunks so that each chunk fits in 254-28-5 bytes.
141 7285a491 2004-06-17 devnull * What a crock.
142 7285a491 2004-06-17 devnull *
143 7285a491 2004-06-17 devnull * The new Plan 9 format uses strings of this form too,
144 7285a491 2004-06-17 devnull * since they're already there.
145 7285a491 2004-06-17 devnull */
146 7285a491 2004-06-17 devnull Cbuf*
147 7285a491 2004-06-17 devnull Cputstring(Cdimg *cd, Cbuf *cp, Cbuf *cn, char *nm, char *p, int flags, int dowrite)
148 7285a491 2004-06-17 devnull {
149 7285a491 2004-06-17 devnull char buf[256], *q;
150 7285a491 2004-06-17 devnull int free;
151 7285a491 2004-06-17 devnull
152 7285a491 2004-06-17 devnull for(; p[0] != '\0'; p = q) {
153 7285a491 2004-06-17 devnull cp = ensurespace(cd, 5+1, cp, cn, dowrite);
154 7285a491 2004-06-17 devnull cp->len -= 5+1;
155 7285a491 2004-06-17 devnull free = freespace(cp);
156 7285a491 2004-06-17 devnull assert(5+1 <= free && free < 256);
157 7285a491 2004-06-17 devnull
158 7285a491 2004-06-17 devnull strncpy(buf, p, free-5);
159 7285a491 2004-06-17 devnull buf[free-5] = '\0';
160 7285a491 2004-06-17 devnull q = p+strlen(buf);
161 7285a491 2004-06-17 devnull p = buf;
162 7285a491 2004-06-17 devnull
163 7285a491 2004-06-17 devnull ensurespace(cd, 5+strlen(p), cp, nil, dowrite); /* nil: better not use this. */
164 7285a491 2004-06-17 devnull Cputrripname(cd, nm, flags | (q[0] ? NMcontinue : 0), p, dowrite);
165 7285a491 2004-06-17 devnull }
166 7285a491 2004-06-17 devnull return cp;
167 7285a491 2004-06-17 devnull }
168 7285a491 2004-06-17 devnull
169 7285a491 2004-06-17 devnull /*
170 7285a491 2004-06-17 devnull * Write a Rock Ridge SUSP set of records for a directory entry.
171 7285a491 2004-06-17 devnull */
172 7285a491 2004-06-17 devnull int
173 7285a491 2004-06-17 devnull Cputsysuse(Cdimg *cd, Direc *d, int dot, int dowrite, int initlen)
174 7285a491 2004-06-17 devnull {
175 7285a491 2004-06-17 devnull char buf[256], buf0[256], *nextpath, *p, *path, *q;
176 7285a491 2004-06-17 devnull int flags, free, m, what;
177 7285a491 2004-06-17 devnull ulong o;
178 7285a491 2004-06-17 devnull Cbuf cn, co, *cp;
179 7285a491 2004-06-17 devnull
180 7285a491 2004-06-17 devnull assert(cd != nil);
181 7285a491 2004-06-17 devnull assert((initlen&1) == 0);
182 7285a491 2004-06-17 devnull
183 7285a491 2004-06-17 devnull if(dot == DTroot)
184 7285a491 2004-06-17 devnull return 0;
185 7285a491 2004-06-17 devnull
186 7285a491 2004-06-17 devnull co.len = initlen;
187 7285a491 2004-06-17 devnull
188 7285a491 2004-06-17 devnull o = Cwoffset(cd);
189 7285a491 2004-06-17 devnull
190 7285a491 2004-06-17 devnull assert(dowrite==0 || Cwoffset(cd) == o+co.len-initlen);
191 7285a491 2004-06-17 devnull cp = &co;
192 7285a491 2004-06-17 devnull
193 7285a491 2004-06-17 devnull if (dot == DTrootdot) {
194 7285a491 2004-06-17 devnull m = CputsuspSP(cd, 0);
195 7285a491 2004-06-17 devnull cp = ensurespace(cd, m, cp, &cn, dowrite);
196 7285a491 2004-06-17 devnull CputsuspSP(cd, dowrite);
197 7285a491 2004-06-17 devnull
198 7285a491 2004-06-17 devnull m = CputsuspER(cd, 0);
199 7285a491 2004-06-17 devnull cp = ensurespace(cd, m, cp, &cn, dowrite);
200 7285a491 2004-06-17 devnull CputsuspER(cd, dowrite);
201 7285a491 2004-06-17 devnull }
202 7285a491 2004-06-17 devnull
203 7285a491 2004-06-17 devnull /*
204 7285a491 2004-06-17 devnull * In a perfect world, we'd be able to omit the NM
205 7285a491 2004-06-17 devnull * entries when our name was all lowercase and conformant,
206 7285a491 2004-06-17 devnull * but OpenBSD insists on uppercasing (really, not lowercasing)
207 7285a491 2004-06-17 devnull * the ISO9660 names.
208 7285a491 2004-06-17 devnull */
209 7285a491 2004-06-17 devnull what = RR_PX | RR_TF | RR_NM;
210 7285a491 2004-06-17 devnull if(d != nil && (d->mode & CHLINK))
211 7285a491 2004-06-17 devnull what |= RR_SL;
212 7285a491 2004-06-17 devnull
213 7285a491 2004-06-17 devnull m = CputsuspRR(cd, what, 0);
214 7285a491 2004-06-17 devnull cp = ensurespace(cd, m, cp, &cn, dowrite);
215 7285a491 2004-06-17 devnull CputsuspRR(cd, what, dowrite);
216 7285a491 2004-06-17 devnull
217 7285a491 2004-06-17 devnull if(what & RR_PX) {
218 7285a491 2004-06-17 devnull m = CputrripPX(cd, d, dot, 0);
219 7285a491 2004-06-17 devnull cp = ensurespace(cd, m, cp, &cn, dowrite);
220 7285a491 2004-06-17 devnull CputrripPX(cd, d, dot, dowrite);
221 7285a491 2004-06-17 devnull }
222 7285a491 2004-06-17 devnull
223 7285a491 2004-06-17 devnull if(what & RR_NM) {
224 7285a491 2004-06-17 devnull if(dot == DTiden)
225 7285a491 2004-06-17 devnull p = d->name;
226 7285a491 2004-06-17 devnull else if(dot == DTdotdot)
227 7285a491 2004-06-17 devnull p = "..";
228 7285a491 2004-06-17 devnull else
229 7285a491 2004-06-17 devnull p = ".";
230 7285a491 2004-06-17 devnull
231 7285a491 2004-06-17 devnull flags = suspdirflags(d, dot);
232 7285a491 2004-06-17 devnull assert(dowrite==0 || cp != &co || Cwoffset(cd) == o+co.len-initlen);
233 7285a491 2004-06-17 devnull cp = Cputstring(cd, cp, &cn, "NM", p, flags, dowrite);
234 7285a491 2004-06-17 devnull }
235 7285a491 2004-06-17 devnull
236 7285a491 2004-06-17 devnull /*
237 7285a491 2004-06-17 devnull * Put down the symbolic link. This is even more of a crock.
238 7285a491 2004-06-17 devnull * Not only are the individual elements potentially split,
239 7285a491 2004-06-17 devnull * but the whole path itself can be split across SL blocks.
240 7285a491 2004-06-17 devnull * To keep the code simple as possible (really), we write
241 7285a491 2004-06-17 devnull * only one element per SL block, wasting 6 bytes per element.
242 7285a491 2004-06-17 devnull */
243 7285a491 2004-06-17 devnull if(what & RR_SL) {
244 7285a491 2004-06-17 devnull for(path=d->symlink; path[0] != '\0'; path=nextpath) {
245 7285a491 2004-06-17 devnull /* break off one component */
246 7285a491 2004-06-17 devnull if((nextpath = strchr(path, '/')) == nil)
247 7285a491 2004-06-17 devnull nextpath = path+strlen(path);
248 7285a491 2004-06-17 devnull strncpy(buf0, path, nextpath-path);
249 7285a491 2004-06-17 devnull buf0[nextpath-path] = '\0';
250 7285a491 2004-06-17 devnull if(nextpath[0] == '/')
251 7285a491 2004-06-17 devnull nextpath++;
252 7285a491 2004-06-17 devnull p = buf0;
253 7285a491 2004-06-17 devnull
254 7285a491 2004-06-17 devnull /* write the name, perhaps broken into pieces */
255 7285a491 2004-06-17 devnull if(strcmp(p, "") == 0)
256 7285a491 2004-06-17 devnull flags = NMroot;
257 7285a491 2004-06-17 devnull else if(strcmp(p, ".") == 0)
258 7285a491 2004-06-17 devnull flags = NMcurrent;
259 7285a491 2004-06-17 devnull else if(strcmp(p, "..") == 0)
260 7285a491 2004-06-17 devnull flags = NMparent;
261 7285a491 2004-06-17 devnull else
262 7285a491 2004-06-17 devnull flags = 0;
263 7285a491 2004-06-17 devnull
264 7285a491 2004-06-17 devnull /* the do-while handles the empty string properly */
265 7285a491 2004-06-17 devnull do {
266 7285a491 2004-06-17 devnull /* must have room for at least 1 byte of name */
267 7285a491 2004-06-17 devnull cp = ensurespace(cd, 7+1, cp, &cn, dowrite);
268 7285a491 2004-06-17 devnull cp->len -= 7+1;
269 7285a491 2004-06-17 devnull free = freespace(cp);
270 7285a491 2004-06-17 devnull assert(7+1 <= free && free < 256);
271 7285a491 2004-06-17 devnull
272 7285a491 2004-06-17 devnull strncpy(buf, p, free-7);
273 7285a491 2004-06-17 devnull buf[free-7] = '\0';
274 7285a491 2004-06-17 devnull q = p+strlen(buf);
275 7285a491 2004-06-17 devnull p = buf;
276 7285a491 2004-06-17 devnull
277 7285a491 2004-06-17 devnull /* nil: better not need to expand */
278 7285a491 2004-06-17 devnull assert(7+strlen(p) <= free);
279 7285a491 2004-06-17 devnull ensurespace(cd, 7+strlen(p), cp, nil, dowrite);
280 7285a491 2004-06-17 devnull CputrripSL(cd, nextpath[0], flags | (q[0] ? NMcontinue : 0), p, dowrite);
281 7285a491 2004-06-17 devnull p = q;
282 7285a491 2004-06-17 devnull } while(p[0] != '\0');
283 7285a491 2004-06-17 devnull }
284 7285a491 2004-06-17 devnull }
285 7285a491 2004-06-17 devnull
286 7285a491 2004-06-17 devnull assert(dowrite==0 || cp != &co || Cwoffset(cd) == o+co.len-initlen);
287 7285a491 2004-06-17 devnull
288 7285a491 2004-06-17 devnull if(what & RR_TF) {
289 7285a491 2004-06-17 devnull m = CputrripTF(cd, d, TFcreation|TFmodify|TFaccess|TFattributes, 0);
290 7285a491 2004-06-17 devnull cp = ensurespace(cd, m, cp, &cn, dowrite);
291 7285a491 2004-06-17 devnull CputrripTF(cd, d, TFcreation|TFmodify|TFaccess|TFattributes, dowrite);
292 7285a491 2004-06-17 devnull }
293 7285a491 2004-06-17 devnull assert(dowrite==0 || cp != &co || Cwoffset(cd) == o+co.len-initlen);
294 7285a491 2004-06-17 devnull
295 7285a491 2004-06-17 devnull if(cp == &cn && dowrite) {
296 7285a491 2004-06-17 devnull /* seek out of continuation, but mark our place */
297 7285a491 2004-06-17 devnull cd->rrcontin = Cwoffset(cd);
298 7285a491 2004-06-17 devnull setcelen(cd, cn.ceoffset, cn.len);
299 7285a491 2004-06-17 devnull Cwseek(cd, o+co.len-initlen);
300 7285a491 2004-06-17 devnull }
301 7285a491 2004-06-17 devnull
302 7285a491 2004-06-17 devnull if(co.len & 1) {
303 7285a491 2004-06-17 devnull co.len++;
304 7285a491 2004-06-17 devnull if(dowrite)
305 7285a491 2004-06-17 devnull Cputc(cd, 0);
306 7285a491 2004-06-17 devnull }
307 7285a491 2004-06-17 devnull
308 7285a491 2004-06-17 devnull if(dowrite) {
309 7285a491 2004-06-17 devnull if(Cwoffset(cd) != o+co.len-initlen)
310 7285a491 2004-06-17 devnull fprint(2, "offset %lud o+co.len-initlen %lud\n", Cwoffset(cd), o+co.len-initlen);
311 7285a491 2004-06-17 devnull assert(Cwoffset(cd) == o+co.len-initlen);
312 7285a491 2004-06-17 devnull } else
313 7285a491 2004-06-17 devnull assert(Cwoffset(cd) == o);
314 7285a491 2004-06-17 devnull
315 7285a491 2004-06-17 devnull assert(co.len <= 255);
316 7285a491 2004-06-17 devnull return co.len - initlen;
317 7285a491 2004-06-17 devnull }
318 7285a491 2004-06-17 devnull
319 7285a491 2004-06-17 devnull static char SUSPrrip[10] = "RRIP_1991A";
320 7285a491 2004-06-17 devnull static char SUSPdesc[84] = "RRIP <more garbage here>";
321 7285a491 2004-06-17 devnull static char SUSPsrc[135] = "RRIP <more garbage here>";
322 7285a491 2004-06-17 devnull
323 7285a491 2004-06-17 devnull static ulong
324 7285a491 2004-06-17 devnull CputsuspCE(Cdimg *cd, ulong offset)
325 7285a491 2004-06-17 devnull {
326 7285a491 2004-06-17 devnull ulong o, x;
327 7285a491 2004-06-17 devnull
328 7285a491 2004-06-17 devnull chat("writing SUSP CE record pointing to %ld, %ld\n", offset/Blocksize, offset%Blocksize);
329 7285a491 2004-06-17 devnull o = Cwoffset(cd);
330 7285a491 2004-06-17 devnull Cputc(cd, 'C');
331 7285a491 2004-06-17 devnull Cputc(cd, 'E');
332 7285a491 2004-06-17 devnull Cputc(cd, 28);
333 7285a491 2004-06-17 devnull Cputc(cd, 1);
334 7285a491 2004-06-17 devnull Cputn(cd, offset/Blocksize, 4);
335 7285a491 2004-06-17 devnull Cputn(cd, offset%Blocksize, 4);
336 7285a491 2004-06-17 devnull x = Cwoffset(cd);
337 7285a491 2004-06-17 devnull Cputn(cd, 0, 4);
338 7285a491 2004-06-17 devnull assert(Cwoffset(cd) == o+28);
339 7285a491 2004-06-17 devnull
340 7285a491 2004-06-17 devnull return x;
341 7285a491 2004-06-17 devnull }
342 7285a491 2004-06-17 devnull
343 7285a491 2004-06-17 devnull static int
344 7285a491 2004-06-17 devnull CputsuspER(Cdimg *cd, int dowrite)
345 7285a491 2004-06-17 devnull {
346 7285a491 2004-06-17 devnull assert(cd != nil);
347 7285a491 2004-06-17 devnull
348 7285a491 2004-06-17 devnull if(dowrite) {
349 7285a491 2004-06-17 devnull chat("writing SUSP ER record\n");
350 7285a491 2004-06-17 devnull Cputc(cd, 'E'); /* ER field marker */
351 7285a491 2004-06-17 devnull Cputc(cd, 'R');
352 7285a491 2004-06-17 devnull Cputc(cd, 26); /* Length */
353 7285a491 2004-06-17 devnull Cputc(cd, 1); /* Version */
354 7285a491 2004-06-17 devnull Cputc(cd, 10); /* LEN_ID */
355 7285a491 2004-06-17 devnull Cputc(cd, 4); /* LEN_DESC */
356 7285a491 2004-06-17 devnull Cputc(cd, 4); /* LEN_SRC */
357 7285a491 2004-06-17 devnull Cputc(cd, 1); /* EXT_VER */
358 7285a491 2004-06-17 devnull Cputs(cd, SUSPrrip, 10); /* EXT_ID */
359 7285a491 2004-06-17 devnull Cputs(cd, SUSPdesc, 4); /* EXT_DESC */
360 7285a491 2004-06-17 devnull Cputs(cd, SUSPsrc, 4); /* EXT_SRC */
361 7285a491 2004-06-17 devnull }
362 7285a491 2004-06-17 devnull return 8+10+4+4;
363 7285a491 2004-06-17 devnull }
364 7285a491 2004-06-17 devnull
365 7285a491 2004-06-17 devnull static int
366 7285a491 2004-06-17 devnull CputsuspRR(Cdimg *cd, int what, int dowrite)
367 7285a491 2004-06-17 devnull {
368 7285a491 2004-06-17 devnull assert(cd != nil);
369 7285a491 2004-06-17 devnull
370 7285a491 2004-06-17 devnull if(dowrite) {
371 7285a491 2004-06-17 devnull Cputc(cd, 'R'); /* RR field marker */
372 7285a491 2004-06-17 devnull Cputc(cd, 'R');
373 7285a491 2004-06-17 devnull Cputc(cd, 5); /* Length */
374 7285a491 2004-06-17 devnull Cputc(cd, 1); /* Version number */
375 7285a491 2004-06-17 devnull Cputc(cd, what); /* Flags */
376 7285a491 2004-06-17 devnull }
377 7285a491 2004-06-17 devnull return 5;
378 7285a491 2004-06-17 devnull }
379 7285a491 2004-06-17 devnull
380 7285a491 2004-06-17 devnull static int
381 7285a491 2004-06-17 devnull CputsuspSP(Cdimg *cd, int dowrite)
382 7285a491 2004-06-17 devnull {
383 7285a491 2004-06-17 devnull assert(cd!=0);
384 7285a491 2004-06-17 devnull
385 7285a491 2004-06-17 devnull if(dowrite) {
386 7285a491 2004-06-17 devnull chat("writing SUSP SP record\n");
387 7285a491 2004-06-17 devnull Cputc(cd, 'S'); /* SP field marker */
388 7285a491 2004-06-17 devnull Cputc(cd, 'P');
389 7285a491 2004-06-17 devnull Cputc(cd, 7); /* Length */
390 7285a491 2004-06-17 devnull Cputc(cd, 1); /* Version */
391 7285a491 2004-06-17 devnull Cputc(cd, 0xBE); /* Magic */
392 7285a491 2004-06-17 devnull Cputc(cd, 0xEF);
393 7285a491 2004-06-17 devnull Cputc(cd, 0);
394 7285a491 2004-06-17 devnull }
395 7285a491 2004-06-17 devnull
396 7285a491 2004-06-17 devnull return 7;
397 7285a491 2004-06-17 devnull }
398 7285a491 2004-06-17 devnull
399 7285a491 2004-06-17 devnull #ifdef NOTUSED
400 7285a491 2004-06-17 devnull static int
401 7285a491 2004-06-17 devnull CputsuspST(Cdimg *cd, int dowrite)
402 7285a491 2004-06-17 devnull {
403 7285a491 2004-06-17 devnull assert(cd!=0);
404 7285a491 2004-06-17 devnull
405 7285a491 2004-06-17 devnull if(dowrite) {
406 7285a491 2004-06-17 devnull Cputc(cd, 'S'); /* ST field marker */
407 7285a491 2004-06-17 devnull Cputc(cd, 'T');
408 7285a491 2004-06-17 devnull Cputc(cd, 4); /* Length */
409 7285a491 2004-06-17 devnull Cputc(cd, 1); /* Version */
410 7285a491 2004-06-17 devnull }
411 7285a491 2004-06-17 devnull return 4;
412 7285a491 2004-06-17 devnull }
413 7285a491 2004-06-17 devnull #endif
414 7285a491 2004-06-17 devnull
415 7285a491 2004-06-17 devnull static ulong
416 7285a491 2004-06-17 devnull suspdirflags(Direc *d, int dot)
417 7285a491 2004-06-17 devnull {
418 7285a491 2004-06-17 devnull uchar flags;
419 7285a491 2004-06-17 devnull
420 7285a491 2004-06-17 devnull USED(d);
421 7285a491 2004-06-17 devnull flags = 0;
422 7285a491 2004-06-17 devnull switch(dot) {
423 7285a491 2004-06-17 devnull default:
424 7285a491 2004-06-17 devnull assert(0);
425 7285a491 2004-06-17 devnull case DTdot:
426 7285a491 2004-06-17 devnull case DTrootdot:
427 7285a491 2004-06-17 devnull flags |= NMcurrent;
428 7285a491 2004-06-17 devnull break;
429 7285a491 2004-06-17 devnull case DTdotdot:
430 7285a491 2004-06-17 devnull flags |= NMparent;
431 7285a491 2004-06-17 devnull break;
432 7285a491 2004-06-17 devnull case DTroot:
433 7285a491 2004-06-17 devnull flags |= NMvolroot;
434 7285a491 2004-06-17 devnull break;
435 7285a491 2004-06-17 devnull case DTiden:
436 7285a491 2004-06-17 devnull break;
437 7285a491 2004-06-17 devnull }
438 7285a491 2004-06-17 devnull return flags;
439 7285a491 2004-06-17 devnull }
440 7285a491 2004-06-17 devnull
441 7285a491 2004-06-17 devnull static int
442 7285a491 2004-06-17 devnull Cputrripname(Cdimg *cd, char *nm, int flags, char *name, int dowrite)
443 7285a491 2004-06-17 devnull {
444 7285a491 2004-06-17 devnull int l;
445 7285a491 2004-06-17 devnull
446 7285a491 2004-06-17 devnull l = strlen(name);
447 7285a491 2004-06-17 devnull if(dowrite) {
448 7285a491 2004-06-17 devnull Cputc(cd, nm[0]); /* NM field marker */
449 7285a491 2004-06-17 devnull Cputc(cd, nm[1]);
450 7285a491 2004-06-17 devnull Cputc(cd, l+5); /* Length */
451 7285a491 2004-06-17 devnull Cputc(cd, 1); /* Version */
452 7285a491 2004-06-17 devnull Cputc(cd, flags); /* Flags */
453 7285a491 2004-06-17 devnull Cputs(cd, name, l); /* Alternate name */
454 7285a491 2004-06-17 devnull }
455 7285a491 2004-06-17 devnull return 5+l;
456 7285a491 2004-06-17 devnull }
457 7285a491 2004-06-17 devnull
458 7285a491 2004-06-17 devnull static int
459 7285a491 2004-06-17 devnull CputrripSL(Cdimg *cd, int contin, int flags, char *name, int dowrite)
460 7285a491 2004-06-17 devnull {
461 7285a491 2004-06-17 devnull int l;
462 7285a491 2004-06-17 devnull
463 7285a491 2004-06-17 devnull l = strlen(name);
464 7285a491 2004-06-17 devnull if(dowrite) {
465 7285a491 2004-06-17 devnull Cputc(cd, 'S');
466 7285a491 2004-06-17 devnull Cputc(cd, 'L');
467 7285a491 2004-06-17 devnull Cputc(cd, l+7);
468 7285a491 2004-06-17 devnull Cputc(cd, 1);
469 7285a491 2004-06-17 devnull Cputc(cd, contin ? 1 : 0);
470 7285a491 2004-06-17 devnull Cputc(cd, flags);
471 7285a491 2004-06-17 devnull Cputc(cd, l);
472 7285a491 2004-06-17 devnull Cputs(cd, name, l);
473 7285a491 2004-06-17 devnull }
474 7285a491 2004-06-17 devnull return 7+l;
475 7285a491 2004-06-17 devnull }
476 7285a491 2004-06-17 devnull
477 7285a491 2004-06-17 devnull static int
478 7285a491 2004-06-17 devnull CputrripPX(Cdimg *cd, Direc *d, int dot, int dowrite)
479 7285a491 2004-06-17 devnull {
480 7285a491 2004-06-17 devnull assert(cd!=0);
481 7285a491 2004-06-17 devnull
482 7285a491 2004-06-17 devnull if(dowrite) {
483 7285a491 2004-06-17 devnull Cputc(cd, 'P'); /* PX field marker */
484 7285a491 2004-06-17 devnull Cputc(cd, 'X');
485 7285a491 2004-06-17 devnull Cputc(cd, 36); /* Length */
486 7285a491 2004-06-17 devnull Cputc(cd, 1); /* Version */
487 7285a491 2004-06-17 devnull
488 7285a491 2004-06-17 devnull Cputn(cd, mode(d, dot), 4); /* POSIX File mode */
489 7285a491 2004-06-17 devnull Cputn(cd, nlink(d), 4); /* POSIX st_nlink */
490 7285a491 2004-06-17 devnull Cputn(cd, d?d->uidno:0, 4); /* POSIX st_uid */
491 7285a491 2004-06-17 devnull Cputn(cd, d?d->gidno:0, 4); /* POSIX st_gid */
492 7285a491 2004-06-17 devnull }
493 7285a491 2004-06-17 devnull
494 7285a491 2004-06-17 devnull return 36;
495 7285a491 2004-06-17 devnull }
496 7285a491 2004-06-17 devnull
497 7285a491 2004-06-17 devnull static int
498 7285a491 2004-06-17 devnull CputrripTF(Cdimg *cd, Direc *d, int type, int dowrite)
499 7285a491 2004-06-17 devnull {
500 7285a491 2004-06-17 devnull int i, length;
501 7285a491 2004-06-17 devnull
502 7285a491 2004-06-17 devnull assert(cd!=0);
503 7285a491 2004-06-17 devnull assert(!(type & TFlongform));
504 7285a491 2004-06-17 devnull
505 7285a491 2004-06-17 devnull length = 0;
506 7285a491 2004-06-17 devnull for(i=0; i<7; i++)
507 7285a491 2004-06-17 devnull if (type & (1<<i))
508 7285a491 2004-06-17 devnull length++;
509 7285a491 2004-06-17 devnull assert(length == 4);
510 7285a491 2004-06-17 devnull
511 7285a491 2004-06-17 devnull if(dowrite) {
512 7285a491 2004-06-17 devnull Cputc(cd, 'T'); /* TF field marker */
513 7285a491 2004-06-17 devnull Cputc(cd, 'F');
514 7285a491 2004-06-17 devnull Cputc(cd, 5+7*length); /* Length */
515 7285a491 2004-06-17 devnull Cputc(cd, 1); /* Version */
516 7285a491 2004-06-17 devnull Cputc(cd, type); /* Flags (types) */
517 7285a491 2004-06-17 devnull
518 7285a491 2004-06-17 devnull if (type & TFcreation)
519 7285a491 2004-06-17 devnull Cputdate(cd, d?d->ctime:0);
520 7285a491 2004-06-17 devnull if (type & TFmodify)
521 7285a491 2004-06-17 devnull Cputdate(cd, d?d->mtime:0);
522 7285a491 2004-06-17 devnull if (type & TFaccess)
523 7285a491 2004-06-17 devnull Cputdate(cd, d?d->atime:0);
524 7285a491 2004-06-17 devnull if (type & TFattributes)
525 7285a491 2004-06-17 devnull Cputdate(cd, d?d->ctime:0);
526 7285a491 2004-06-17 devnull
527 cbeb0b26 2006-04-01 devnull /* if (type & TFbackup) */
528 cbeb0b26 2006-04-01 devnull /* Cputdate(cd, 0); */
529 cbeb0b26 2006-04-01 devnull /* if (type & TFexpiration) */
530 cbeb0b26 2006-04-01 devnull /* Cputdate(cd, 0); */
531 cbeb0b26 2006-04-01 devnull /* if (type & TFeffective) */
532 cbeb0b26 2006-04-01 devnull /* Cputdate(cd, 0); */
533 7285a491 2004-06-17 devnull }
534 7285a491 2004-06-17 devnull return 5+7*length;
535 7285a491 2004-06-17 devnull }
536 7285a491 2004-06-17 devnull
537 7285a491 2004-06-17 devnull
538 7285a491 2004-06-17 devnull #define NONPXMODES (DMDIR & DMAPPEND & DMEXCL & DMMOUNT)
539 7285a491 2004-06-17 devnull #define POSIXMODEMASK (0177777)
540 7285a491 2004-06-17 devnull #ifndef S_IFMT
541 7285a491 2004-06-17 devnull #define S_IFMT (0170000)
542 7285a491 2004-06-17 devnull #endif
543 7285a491 2004-06-17 devnull #ifndef S_IFDIR
544 7285a491 2004-06-17 devnull #define S_IFDIR (0040000)
545 7285a491 2004-06-17 devnull #endif
546 7285a491 2004-06-17 devnull #ifndef S_IFREG
547 7285a491 2004-06-17 devnull #define S_IFREG (0100000)
548 7285a491 2004-06-17 devnull #endif
549 7285a491 2004-06-17 devnull #ifndef S_IFLNK
550 7285a491 2004-06-17 devnull #define S_IFLNK (0120000)
551 7285a491 2004-06-17 devnull #endif
552 7285a491 2004-06-17 devnull #undef ISTYPE
553 7285a491 2004-06-17 devnull #define ISTYPE(mode, mask) (((mode) & S_IFMT) == (mask))
554 7285a491 2004-06-17 devnull #ifndef S_ISDIR
555 7285a491 2004-06-17 devnull #define S_ISDIR(mode) ISTYPE(mode, S_IFDIR)
556 7285a491 2004-06-17 devnull #endif
557 7285a491 2004-06-17 devnull #ifndef S_ISREG
558 7285a491 2004-06-17 devnull #define S_ISREG(mode) ISTYPE(mode, S_IREG)
559 7285a491 2004-06-17 devnull #endif
560 7285a491 2004-06-17 devnull #ifndef S_ISLNK
561 7285a491 2004-06-17 devnull #define S_ISLNK(mode) ISTYPE(mode, S_ILNK)
562 7285a491 2004-06-17 devnull #endif
563 7285a491 2004-06-17 devnull
564 7285a491 2004-06-17 devnull
565 7285a491 2004-06-17 devnull static long
566 7285a491 2004-06-17 devnull mode(Direc *d, int dot)
567 7285a491 2004-06-17 devnull {
568 7285a491 2004-06-17 devnull long mode;
569 7285a491 2004-06-17 devnull
570 7285a491 2004-06-17 devnull if (!d)
571 7285a491 2004-06-17 devnull return 0;
572 7285a491 2004-06-17 devnull
573 7285a491 2004-06-17 devnull if ((dot != DTroot) && (dot != DTrootdot)) {
574 7285a491 2004-06-17 devnull mode = (d->mode & ~(NONPXMODES));
575 7285a491 2004-06-17 devnull if (d->mode & DMDIR)
576 7285a491 2004-06-17 devnull mode |= S_IFDIR;
577 7285a491 2004-06-17 devnull else if (d->mode & CHLINK)
578 7285a491 2004-06-17 devnull mode |= S_IFLNK;
579 7285a491 2004-06-17 devnull else
580 7285a491 2004-06-17 devnull mode |= S_IFREG;
581 7285a491 2004-06-17 devnull } else
582 7285a491 2004-06-17 devnull mode = S_IFDIR | (0755);
583 7285a491 2004-06-17 devnull
584 7285a491 2004-06-17 devnull mode &= POSIXMODEMASK;
585 7285a491 2004-06-17 devnull
586 7285a491 2004-06-17 devnull /* Botch: not all POSIX types supported yet */
587 7285a491 2004-06-17 devnull assert(mode & (S_IFDIR|S_IFREG));
588 7285a491 2004-06-17 devnull
589 7285a491 2004-06-17 devnull chat("writing PX record mode field %ulo with dot %d and name \"%s\"\n", mode, dot, d->name);
590 7285a491 2004-06-17 devnull
591 7285a491 2004-06-17 devnull return mode;
592 7285a491 2004-06-17 devnull }
593 7285a491 2004-06-17 devnull
594 7285a491 2004-06-17 devnull static long
595 7285a491 2004-06-17 devnull nlink(Direc *d) /* Trump up the nlink field for POSIX compliance */
596 7285a491 2004-06-17 devnull {
597 7285a491 2004-06-17 devnull int i;
598 7285a491 2004-06-17 devnull long n;
599 7285a491 2004-06-17 devnull
600 7285a491 2004-06-17 devnull if (!d)
601 7285a491 2004-06-17 devnull return 0;
602 7285a491 2004-06-17 devnull
603 7285a491 2004-06-17 devnull n = 1;
604 7285a491 2004-06-17 devnull if (d->mode & DMDIR) /* One for "." and one more for ".." */
605 7285a491 2004-06-17 devnull n++;
606 7285a491 2004-06-17 devnull
607 7285a491 2004-06-17 devnull for(i=0; i<d->nchild; i++)
608 7285a491 2004-06-17 devnull if (d->child[i].mode & DMDIR)
609 7285a491 2004-06-17 devnull n++;
610 7285a491 2004-06-17 devnull
611 7285a491 2004-06-17 devnull return n;
612 7285a491 2004-06-17 devnull }
613 7285a491 2004-06-17 devnull