File: | isofs/cd9660/cd9660_rrip.c |
Warning: | line 227, column 2 Value stored to 'wlen' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: cd9660_rrip.c,v 1.17 2023/03/08 04:43:08 guenther Exp $ */ |
2 | /* $NetBSD: cd9660_rrip.c,v 1.17 1997/01/24 00:27:32 cgd Exp $ */ |
3 | |
4 | /*- |
5 | * Copyright (c) 1993, 1994 |
6 | * The Regents of the University of California. All rights reserved. |
7 | * |
8 | * This code is derived from software contributed to Berkeley |
9 | * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension |
10 | * Support code is derived from software contributed to Berkeley |
11 | * by Atsushi Murai (amurai@spec.co.jp). |
12 | * |
13 | * Redistribution and use in source and binary forms, with or without |
14 | * modification, are permitted provided that the following conditions |
15 | * are met: |
16 | * 1. Redistributions of source code must retain the above copyright |
17 | * notice, this list of conditions and the following disclaimer. |
18 | * 2. Redistributions in binary form must reproduce the above copyright |
19 | * notice, this list of conditions and the following disclaimer in the |
20 | * documentation and/or other materials provided with the distribution. |
21 | * 3. Neither the name of the University nor the names of its contributors |
22 | * may be used to endorse or promote products derived from this software |
23 | * without specific prior written permission. |
24 | * |
25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
28 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
33 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
34 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
35 | * SUCH DAMAGE. |
36 | * |
37 | * @(#)cd9660_rrip.c 8.6 (Berkeley) 12/5/94 |
38 | */ |
39 | |
40 | #include <sys/param.h> |
41 | #include <sys/systm.h> |
42 | #include <sys/namei.h> |
43 | #include <sys/buf.h> |
44 | #include <sys/vnode.h> |
45 | #include <sys/lock.h> |
46 | #include <sys/mount.h> |
47 | #include <sys/kernel.h> |
48 | #include <sys/stat.h> |
49 | #include <sys/time.h> |
50 | |
51 | #include <isofs/cd9660/iso.h> |
52 | #include <isofs/cd9660/cd9660_extern.h> |
53 | #include <isofs/cd9660/cd9660_node.h> |
54 | #include <isofs/cd9660/cd9660_rrip.h> |
55 | #include <isofs/cd9660/iso_rrip.h> |
56 | |
57 | typedef struct { |
58 | char type[2]; |
59 | int (*func)(void *, ISO_RRIP_ANALYZE *); |
60 | void (*func2)(void *, ISO_RRIP_ANALYZE *); |
61 | int result; |
62 | } RRIP_TABLE; |
63 | |
64 | static int cd9660_rrip_attr(void *, ISO_RRIP_ANALYZE *); |
65 | static void cd9660_rrip_defattr(void *, ISO_RRIP_ANALYZE *); |
66 | static int cd9660_rrip_slink(void *, ISO_RRIP_ANALYZE *); |
67 | static int cd9660_rrip_altname(void *, ISO_RRIP_ANALYZE *); |
68 | static void cd9660_rrip_defname(void *, ISO_RRIP_ANALYZE *); |
69 | static int cd9660_rrip_pclink(void *, ISO_RRIP_ANALYZE *); |
70 | static int cd9660_rrip_reldir(void *, ISO_RRIP_ANALYZE *); |
71 | static int cd9660_rrip_tstamp(void *, ISO_RRIP_ANALYZE *); |
72 | static void cd9660_rrip_deftstamp(void *, ISO_RRIP_ANALYZE *); |
73 | static int cd9660_rrip_device(void *, ISO_RRIP_ANALYZE *); |
74 | static int cd9660_rrip_idflag(void *, ISO_RRIP_ANALYZE *); |
75 | static int cd9660_rrip_cont(void *, ISO_RRIP_ANALYZE *); |
76 | static int cd9660_rrip_stop(void *, ISO_RRIP_ANALYZE *); |
77 | static int cd9660_rrip_extref(void *, ISO_RRIP_ANALYZE *); |
78 | static int cd9660_rrip_loop(struct iso_directory_record *, |
79 | ISO_RRIP_ANALYZE *, RRIP_TABLE *); |
80 | /* |
81 | * POSIX file attribute |
82 | */ |
83 | static int |
84 | cd9660_rrip_attr(void *v, ISO_RRIP_ANALYZE *ana) |
85 | { |
86 | ISO_RRIP_ATTR *p = v; |
87 | |
88 | ana->inop->inode.iso_mode = isonum_733(p->mode); |
89 | ana->inop->inode.iso_uid = isonum_733(p->uid); |
90 | ana->inop->inode.iso_gid = isonum_733(p->gid); |
91 | ana->inop->inode.iso_links = isonum_733(p->links); |
92 | ana->fields &= ~ISO_SUSP_ATTR0x0001; |
93 | return (ISO_SUSP_ATTR0x0001); |
94 | } |
95 | |
96 | static void |
97 | cd9660_rrip_defattr(void *v, ISO_RRIP_ANALYZE *ana) |
98 | { |
99 | struct iso_directory_record *isodir = v; |
100 | |
101 | /* But this is a required field! */ |
102 | printf("RRIP without PX field?\n"); |
103 | cd9660_defattr(isodir, ana->inop, NULL((void *)0)); |
104 | } |
105 | |
106 | /* |
107 | * Symbolic Links |
108 | */ |
109 | static int |
110 | cd9660_rrip_slink(void *v, ISO_RRIP_ANALYZE *ana) |
111 | { |
112 | ISO_RRIP_SLINK *p = v; |
113 | ISO_RRIP_SLINK_COMPONENT *pcomp; |
114 | ISO_RRIP_SLINK_COMPONENT *pcompe; |
115 | int len, wlen, cont; |
116 | char *outbuf, *inbuf; |
117 | |
118 | pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component; |
119 | pcompe = |
120 | (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length)); |
121 | len = *ana->outlen; |
122 | outbuf = ana->outbuf; |
123 | cont = ana->cont; |
124 | |
125 | /* |
126 | * Gathering a Symbolic name from each component with path |
127 | */ |
128 | for (; pcomp < pcompe; |
129 | pcomp = (ISO_RRIP_SLINK_COMPONENT *) |
130 | ((char *)pcomp + ISO_RRIP_SLSIZ2 + isonum_711(pcomp->clen))) { |
131 | |
132 | if (!cont) { |
133 | if (len < ana->maxlen) { |
134 | len++; |
135 | *outbuf++ = '/'; |
136 | } |
137 | } |
138 | cont = 0; |
139 | |
140 | inbuf = ".."; |
141 | wlen = 0; |
142 | |
143 | switch (*pcomp->cflag) { |
144 | |
145 | case ISO_SUSP_CFLAG_CURRENT0x02: |
146 | /* Inserting Current */ |
147 | wlen = 1; |
148 | break; |
149 | |
150 | case ISO_SUSP_CFLAG_PARENT0x04: |
151 | /* Inserting Parent */ |
152 | wlen = 2; |
153 | break; |
154 | |
155 | case ISO_SUSP_CFLAG_ROOT0x08: |
156 | /* Inserting slash for ROOT */ |
157 | /* start over from beginning(?) */ |
158 | outbuf -= len; |
159 | len = 0; |
160 | break; |
161 | |
162 | case ISO_SUSP_CFLAG_VOLROOT0x10: |
163 | /* Inserting a mount point i.e. "/cdrom" */ |
164 | /* same as above */ |
165 | outbuf -= len; |
166 | len = 0; |
167 | inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname; |
168 | wlen = strlen(inbuf); |
169 | break; |
170 | |
171 | case ISO_SUSP_CFLAG_HOST0x20: |
172 | /* Inserting hostname i.e. "kurt.tools.de" */ |
173 | inbuf = hostname; |
174 | wlen = hostnamelen; |
175 | break; |
176 | |
177 | case ISO_SUSP_CFLAG_CONTINUE0x01: |
178 | cont = 1; |
179 | /* FALLTHROUGH */ |
180 | case 0: |
181 | /* Inserting component */ |
182 | wlen = isonum_711(pcomp->clen); |
183 | inbuf = pcomp->name; |
184 | break; |
185 | default: |
186 | printf("RRIP with incorrect flags?"); |
187 | wlen = ana->maxlen + 1; |
188 | break; |
189 | } |
190 | |
191 | if (len + wlen > ana->maxlen) { |
192 | /* indicate error to caller */ |
193 | ana->cont = 1; |
194 | ana->fields = 0; |
195 | ana->outbuf -= *ana->outlen; |
196 | *ana->outlen = 0; |
197 | return (0); |
198 | } |
199 | |
200 | bcopy(inbuf, outbuf, wlen); |
201 | outbuf += wlen; |
202 | len += wlen; |
203 | } |
204 | ana->outbuf = outbuf; |
205 | *ana->outlen = len; |
206 | ana->cont = cont; |
207 | |
208 | if (!isonum_711(p->flags)) { |
209 | ana->fields &= ~ISO_SUSP_SLINK0x0004; |
210 | return (ISO_SUSP_SLINK0x0004); |
211 | } |
212 | return (0); |
213 | } |
214 | |
215 | /* |
216 | * Alternate name |
217 | */ |
218 | static int |
219 | cd9660_rrip_altname(void *v, ISO_RRIP_ANALYZE *ana) |
220 | { |
221 | ISO_RRIP_ALTNAME *p = v; |
222 | char *inbuf; |
223 | int wlen; |
224 | int cont; |
225 | |
226 | inbuf = ".."; |
227 | wlen = 0; |
Value stored to 'wlen' is never read | |
228 | cont = 0; |
229 | |
230 | switch (*p->flags) { |
231 | case ISO_SUSP_CFLAG_CURRENT0x02: |
232 | /* Inserting Current */ |
233 | wlen = 1; |
234 | break; |
235 | |
236 | case ISO_SUSP_CFLAG_PARENT0x04: |
237 | /* Inserting Parent */ |
238 | wlen = 2; |
239 | break; |
240 | |
241 | case ISO_SUSP_CFLAG_HOST0x20: |
242 | /* Inserting hostname i.e. "kurt.tools.de" */ |
243 | inbuf = hostname; |
244 | wlen = hostnamelen; |
245 | break; |
246 | |
247 | case ISO_SUSP_CFLAG_CONTINUE0x01: |
248 | cont = 1; |
249 | /* FALLTHROUGH */ |
250 | case 0: |
251 | /* Inserting component */ |
252 | wlen = isonum_711(p->h.length) - 5; |
253 | inbuf = (char *)p + 5; |
254 | break; |
255 | |
256 | default: |
257 | printf("RRIP with incorrect NM flags?\n"); |
258 | wlen = ana->maxlen + 1; |
259 | break; |
260 | } |
261 | |
262 | if ((*ana->outlen += wlen) > ana->maxlen) { |
263 | /* treat as no name field */ |
264 | ana->fields &= ~ISO_SUSP_ALTNAME0x0008; |
265 | ana->outbuf -= *ana->outlen - wlen; |
266 | *ana->outlen = 0; |
267 | return (0); |
268 | } |
269 | |
270 | bcopy(inbuf, ana->outbuf, wlen); |
271 | ana->outbuf += wlen; |
272 | |
273 | if (!cont) { |
274 | ana->fields &= ~ISO_SUSP_ALTNAME0x0008; |
275 | return (ISO_SUSP_ALTNAME0x0008); |
276 | } |
277 | return (0); |
278 | } |
279 | |
280 | static void |
281 | cd9660_rrip_defname(void *v, ISO_RRIP_ANALYZE *ana) |
282 | { |
283 | struct iso_directory_record *isodir = v; |
284 | |
285 | strlcpy(ana->outbuf, "..", ana->maxlen - *ana->outlen); |
286 | switch (*isodir->name) { |
287 | default: |
288 | isofntrans(isodir->name, isonum_711(isodir->name_len), |
289 | ana->outbuf, ana->outlen, 1, |
290 | isonum_711(isodir->flags) & 4, ana->imp->joliet_level); |
291 | break; |
292 | case 0: |
293 | *ana->outlen = 1; |
294 | break; |
295 | case 1: |
296 | *ana->outlen = 2; |
297 | break; |
298 | } |
299 | } |
300 | |
301 | /* |
302 | * Parent or Child Link |
303 | */ |
304 | static int |
305 | cd9660_rrip_pclink(void *v, ISO_RRIP_ANALYZE *ana) |
306 | { |
307 | ISO_RRIP_CLINK *p = v; |
308 | |
309 | *ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift; |
310 | ana->fields &= ~(ISO_SUSP_CLINK0x0010 | ISO_SUSP_PLINK0x0020); |
311 | return (*p->h.type == 'C' ? ISO_SUSP_CLINK0x0010 : ISO_SUSP_PLINK0x0020); |
312 | } |
313 | |
314 | /* |
315 | * Relocated directory |
316 | */ |
317 | static int |
318 | cd9660_rrip_reldir(void *v, ISO_RRIP_ANALYZE *ana) |
319 | { |
320 | /* special hack to make caller aware of RE field */ |
321 | *ana->outlen = 0; |
322 | ana->fields = 0; |
323 | return (ISO_SUSP_RELDIR0x0040 | ISO_SUSP_ALTNAME0x0008 | ISO_SUSP_CLINK0x0010 | |
324 | ISO_SUSP_PLINK0x0020); |
325 | } |
326 | |
327 | static int |
328 | cd9660_rrip_tstamp(void *v, ISO_RRIP_ANALYZE *ana) |
329 | { |
330 | ISO_RRIP_TSTAMP *p = v; |
331 | u_char *ptime; |
332 | |
333 | ptime = p->time; |
334 | |
335 | /* Check a format of time stamp (7bytes/17bytes) */ |
336 | if (!(*p->flags & ISO_SUSP_TSTAMP_FORM170x80)) { |
337 | if (*p->flags & ISO_SUSP_TSTAMP_CREAT0x01) |
338 | ptime += 7; |
339 | |
340 | if (*p->flags & ISO_SUSP_TSTAMP_MODIFY0x02) { |
341 | cd9660_tstamp_conv7(ptime, |
342 | &ana->inop->inode.iso_mtime); |
343 | ptime += 7; |
344 | } else |
345 | bzero(&ana->inop->inode.iso_mtime,__builtin_bzero((&ana->inop->inode.iso_mtime), (sizeof (struct timespec))) |
346 | sizeof(struct timespec))__builtin_bzero((&ana->inop->inode.iso_mtime), (sizeof (struct timespec))); |
347 | |
348 | if (*p->flags & ISO_SUSP_TSTAMP_ACCESS0x04) { |
349 | cd9660_tstamp_conv7(ptime, |
350 | &ana->inop->inode.iso_atime); |
351 | ptime += 7; |
352 | } else |
353 | ana->inop->inode.iso_atime = |
354 | ana->inop->inode.iso_mtime; |
355 | |
356 | if (*p->flags & ISO_SUSP_TSTAMP_ATTR0x08) |
357 | cd9660_tstamp_conv7(ptime, |
358 | &ana->inop->inode.iso_ctime); |
359 | else |
360 | ana->inop->inode.iso_ctime = |
361 | ana->inop->inode.iso_mtime; |
362 | |
363 | } else { |
364 | if (*p->flags & ISO_SUSP_TSTAMP_CREAT0x01) |
365 | ptime += 17; |
366 | |
367 | if (*p->flags & ISO_SUSP_TSTAMP_MODIFY0x02) { |
368 | cd9660_tstamp_conv17(ptime, |
369 | &ana->inop->inode.iso_mtime); |
370 | ptime += 17; |
371 | } else |
372 | bzero(&ana->inop->inode.iso_mtime,__builtin_bzero((&ana->inop->inode.iso_mtime), (sizeof (struct timespec))) |
373 | sizeof(struct timespec))__builtin_bzero((&ana->inop->inode.iso_mtime), (sizeof (struct timespec))); |
374 | |
375 | if (*p->flags & ISO_SUSP_TSTAMP_ACCESS0x04) { |
376 | cd9660_tstamp_conv17(ptime, |
377 | &ana->inop->inode.iso_atime); |
378 | ptime += 17; |
379 | } else |
380 | ana->inop->inode.iso_atime = |
381 | ana->inop->inode.iso_mtime; |
382 | |
383 | if (*p->flags & ISO_SUSP_TSTAMP_ATTR0x08) |
384 | cd9660_tstamp_conv17(ptime, |
385 | &ana->inop->inode.iso_ctime); |
386 | else |
387 | ana->inop->inode.iso_ctime = |
388 | ana->inop->inode.iso_mtime; |
389 | |
390 | } |
391 | ana->fields &= ~ISO_SUSP_TSTAMP0x0080; |
392 | return (ISO_SUSP_TSTAMP0x0080); |
393 | } |
394 | |
395 | static void |
396 | cd9660_rrip_deftstamp(void *v, ISO_RRIP_ANALYZE *ana) |
397 | { |
398 | struct iso_directory_record *isodir = v; |
399 | |
400 | cd9660_deftstamp(isodir, ana->inop, NULL((void *)0)); |
401 | } |
402 | |
403 | /* |
404 | * POSIX device modes |
405 | */ |
406 | static int |
407 | cd9660_rrip_device(void *v, ISO_RRIP_ANALYZE *ana) |
408 | { |
409 | ISO_RRIP_DEVICE *p = v; |
410 | u_int high, low; |
411 | |
412 | high = isonum_733(p->dev_t_high); |
413 | low = isonum_733(p->dev_t_low); |
414 | |
415 | if (high == 0) |
416 | ana->inop->inode.iso_rdev = makedev(major(low), minor(low))((dev_t)(((((((unsigned)(low) >> 8) & 0xff)) & 0xff ) << 8) | ((((unsigned)((low) & 0xff) | (((low) & 0xffff0000) >> 8))) & 0xff) | (((((unsigned)((low) & 0xff) | (((low) & 0xffff0000) >> 8))) & 0xffff00 ) << 8))); |
417 | else |
418 | ana->inop->inode.iso_rdev = makedev(high, minor(low))((dev_t)((((high) & 0xff) << 8) | ((((unsigned)((low ) & 0xff) | (((low) & 0xffff0000) >> 8))) & 0xff) | (((((unsigned)((low) & 0xff) | (((low) & 0xffff0000 ) >> 8))) & 0xffff00) << 8))); |
419 | ana->fields &= ~ISO_SUSP_DEVICE0x0002; |
420 | return (ISO_SUSP_DEVICE0x0002); |
421 | } |
422 | |
423 | /* |
424 | * Flag indicating |
425 | */ |
426 | static int |
427 | cd9660_rrip_idflag(void *v, ISO_RRIP_ANALYZE *ana) |
428 | { |
429 | ISO_RRIP_IDFLAG *p = v; |
430 | |
431 | /* don't touch high bits */ |
432 | ana->fields &= isonum_711(p->flags) | ~0xff; |
433 | /* special handling of RE field */ |
434 | if (ana->fields & ISO_SUSP_RELDIR0x0040) |
435 | return (cd9660_rrip_reldir(p, ana)); |
436 | |
437 | return (ISO_SUSP_IDFLAG0x0100); |
438 | } |
439 | |
440 | /* |
441 | * Continuation pointer |
442 | */ |
443 | static int |
444 | cd9660_rrip_cont(void *v, ISO_RRIP_ANALYZE *ana) |
445 | { |
446 | ISO_RRIP_CONT *p = v; |
447 | |
448 | ana->iso_ce_blk = isonum_733(p->location); |
449 | ana->iso_ce_off = isonum_733(p->offset); |
450 | ana->iso_ce_len = isonum_733(p->length); |
451 | return (ISO_SUSP_CONT0x0400); |
452 | } |
453 | |
454 | /* |
455 | * System Use end |
456 | */ |
457 | static int |
458 | cd9660_rrip_stop(void *v, ISO_RRIP_ANALYZE *ana) |
459 | { |
460 | return (ISO_SUSP_STOP0x1000); |
461 | } |
462 | |
463 | /* |
464 | * Extension reference |
465 | */ |
466 | static int |
467 | cd9660_rrip_extref(void *v, ISO_RRIP_ANALYZE *ana) |
468 | { |
469 | ISO_RRIP_EXTREF *p = v; |
470 | |
471 | if (isonum_711(p->version) != 1) |
472 | return (0); |
473 | if (isonum_711(p->len_id) != 9 && |
474 | isonum_711(p->len_id) != 10) |
475 | return (0); |
476 | if (isonum_711(p->len_id) == 9 && |
477 | bcmp((char *)p + 8, "IEEE_1282", 9)) |
478 | return (0); |
479 | if (isonum_711(p->len_id) == 10 && |
480 | bcmp((char *)p + 8, "IEEE_P1282", 10) && |
481 | bcmp((char *)p + 8, "RRIP_1991A", 10)) |
482 | return (0); |
483 | ana->fields &= ~ISO_SUSP_EXTREF0x0200; |
484 | return (ISO_SUSP_EXTREF0x0200); |
485 | } |
486 | |
487 | |
488 | static int |
489 | cd9660_rrip_loop(struct iso_directory_record *isodir, ISO_RRIP_ANALYZE *ana, |
490 | RRIP_TABLE *table) |
491 | { |
492 | RRIP_TABLE *ptable; |
493 | ISO_SUSP_HEADER *phead; |
494 | ISO_SUSP_HEADER *pend; |
495 | struct buf *bp = NULL((void *)0); |
496 | char *pwhead; |
497 | u_char c; |
498 | int result; |
499 | |
500 | /* |
501 | * Note: If name length is odd, |
502 | * it will be padded by 1 byte after the name |
503 | */ |
504 | pwhead = isodir->name + isonum_711(isodir->name_len); |
505 | if (!(isonum_711(isodir->name_len) & 1)) |
506 | pwhead++; |
507 | isochar(isodir->name, pwhead, ana->imp->joliet_level, &c); |
508 | |
509 | /* If it's not the '.' entry of the root dir obey SP field */ |
510 | if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent) |
511 | pwhead += ana->imp->rr_skip; |
512 | else |
513 | pwhead += ana->imp->rr_skip0; |
514 | |
515 | phead = (ISO_SUSP_HEADER *)pwhead; |
516 | pend = |
517 | (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length)); |
518 | |
519 | result = 0; |
520 | while (1) { |
521 | ana->iso_ce_len = 0; |
522 | /* |
523 | * Note: "pend" should be more than one SUSP header |
524 | */ |
525 | while (pend >= phead + 1) { |
526 | if (isonum_711(phead->version) == 1) { |
527 | for (ptable = table; ptable->func; ptable++) { |
528 | if (*phead->type == *ptable->type && |
529 | phead->type[1] == ptable->type[1]) |
530 | { |
531 | result |= |
532 | ptable->func(phead, ana); |
533 | break; |
534 | } |
535 | } |
536 | if (!ana->fields) |
537 | break; |
538 | } |
539 | if (result & ISO_SUSP_STOP0x1000) { |
540 | result &= ~ISO_SUSP_STOP0x1000; |
541 | break; |
542 | } |
543 | /* plausibility check */ |
544 | if (isonum_711(phead->length) < sizeof(*phead)) |
545 | break; |
546 | /* |
547 | * move to next SUSP |
548 | * Hopefully this works with newer versions, too |
549 | */ |
550 | phead = (ISO_SUSP_HEADER *) |
551 | ((char *)phead + isonum_711(phead->length)); |
552 | } |
553 | |
554 | if (ana->fields && ana->iso_ce_len) { |
555 | if (ana->iso_ce_blk >= ana->imp->volume_space_size || |
556 | ana->iso_ce_off + ana->iso_ce_len > |
557 | ana->imp->logical_block_size || |
558 | bread(ana->imp->im_devvp, ana->iso_ce_blk << |
559 | (ana->imp->im_bshift - DEV_BSHIFT9), |
560 | ana->imp->logical_block_size, &bp)) |
561 | /* what to do now? */ |
562 | break; |
563 | phead = |
564 | (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off); |
565 | pend = (ISO_SUSP_HEADER *) |
566 | ((char *)phead + ana->iso_ce_len); |
567 | } else |
568 | break; |
569 | } |
570 | if (bp) |
571 | brelse(bp); |
572 | /* |
573 | * If we don't find the Basic SUSP stuffs, just set default value |
574 | * (attribute/time stamp) |
575 | */ |
576 | for (ptable = table; ptable->func2; ptable++) |
577 | if (!(ptable->result & result)) |
578 | ptable->func2(isodir, ana); |
579 | |
580 | return (result); |
581 | } |
582 | |
583 | /* |
584 | * Get Attributes. |
585 | */ |
586 | static RRIP_TABLE rrip_table_analyze[] = { |
587 | { "PX", cd9660_rrip_attr, cd9660_rrip_defattr, |
588 | ISO_SUSP_ATTR0x0001 }, |
589 | { "TF", cd9660_rrip_tstamp, cd9660_rrip_deftstamp, |
590 | ISO_SUSP_TSTAMP0x0080 }, |
591 | { "PN", cd9660_rrip_device, 0, |
592 | ISO_SUSP_DEVICE0x0002 }, |
593 | { "RR", cd9660_rrip_idflag, 0, |
594 | ISO_SUSP_IDFLAG0x0100 }, |
595 | { "CE", cd9660_rrip_cont, 0, |
596 | ISO_SUSP_CONT0x0400 }, |
597 | { "ST", cd9660_rrip_stop, 0, |
598 | ISO_SUSP_STOP0x1000 }, |
599 | { "", 0, 0, |
600 | 0 } |
601 | }; |
602 | |
603 | int |
604 | cd9660_rrip_analyze(struct iso_directory_record *isodir, struct iso_node *inop, |
605 | struct iso_mnt *imp) |
606 | { |
607 | ISO_RRIP_ANALYZE analyze; |
608 | |
609 | analyze.inop = inop; |
610 | analyze.imp = imp; |
611 | analyze.fields = ISO_SUSP_ATTR0x0001 | ISO_SUSP_TSTAMP0x0080 | ISO_SUSP_DEVICE0x0002; |
612 | |
613 | return (cd9660_rrip_loop(isodir, &analyze, rrip_table_analyze)); |
614 | } |
615 | |
616 | /* |
617 | * Get Alternate Name. |
618 | */ |
619 | static RRIP_TABLE rrip_table_getname[] = { |
620 | { "NM", cd9660_rrip_altname, cd9660_rrip_defname, |
621 | ISO_SUSP_ALTNAME0x0008 }, |
622 | { "CL", cd9660_rrip_pclink, 0, |
623 | ISO_SUSP_CLINK0x0010|ISO_SUSP_PLINK0x0020 }, |
624 | { "PL", cd9660_rrip_pclink, 0, |
625 | ISO_SUSP_CLINK0x0010|ISO_SUSP_PLINK0x0020 }, |
626 | { "RE", cd9660_rrip_reldir, 0, |
627 | ISO_SUSP_RELDIR0x0040 }, |
628 | { "RR", cd9660_rrip_idflag, 0, |
629 | ISO_SUSP_IDFLAG0x0100 }, |
630 | { "CE", cd9660_rrip_cont, 0, |
631 | ISO_SUSP_CONT0x0400 }, |
632 | { "ST", cd9660_rrip_stop, 0, |
633 | ISO_SUSP_STOP0x1000 }, |
634 | { "", 0, 0, |
635 | 0 } |
636 | }; |
637 | |
638 | int |
639 | cd9660_rrip_getname(struct iso_directory_record *isodir, char *outbuf, |
640 | u_short *outlen, cdino_t *inump, struct iso_mnt *imp) |
641 | { |
642 | ISO_RRIP_ANALYZE analyze; |
643 | RRIP_TABLE *tab; |
644 | u_char c; |
645 | |
646 | analyze.outbuf = outbuf; |
647 | analyze.outlen = outlen; |
648 | analyze.maxlen = NAME_MAX255; |
649 | analyze.inump = inump; |
650 | analyze.imp = imp; |
651 | analyze.fields = ISO_SUSP_ALTNAME0x0008 | ISO_SUSP_RELDIR0x0040 | ISO_SUSP_CLINK0x0010 | |
652 | ISO_SUSP_PLINK0x0020; |
653 | *outlen = 0; |
654 | |
655 | isochar(isodir->name, isodir->name + isonum_711(isodir->name_len), |
656 | imp->joliet_level, &c); |
657 | tab = rrip_table_getname; |
658 | if (c == 0 || c == 1) { |
659 | cd9660_rrip_defname(isodir, &analyze); |
660 | |
661 | analyze.fields &= ~ISO_SUSP_ALTNAME0x0008; |
662 | tab++; |
663 | } |
664 | |
665 | return (cd9660_rrip_loop(isodir, &analyze, tab)); |
666 | } |
667 | |
668 | /* |
669 | * Get Symbolic Link. |
670 | */ |
671 | static RRIP_TABLE rrip_table_getsymname[] = { |
672 | { "SL", cd9660_rrip_slink, 0, ISO_SUSP_SLINK0x0004 }, |
673 | { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG0x0100 }, |
674 | { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT0x0400 }, |
675 | { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP0x1000 }, |
676 | { "", 0, 0, 0 } |
677 | }; |
678 | |
679 | int |
680 | cd9660_rrip_getsymname(struct iso_directory_record *isodir, char *outbuf, |
681 | u_short *outlen, struct iso_mnt *imp) |
682 | { |
683 | ISO_RRIP_ANALYZE analyze; |
684 | |
685 | analyze.outbuf = outbuf; |
686 | analyze.outlen = outlen; |
687 | *outlen = 0; |
688 | analyze.maxlen = MAXPATHLEN1024; |
689 | analyze.cont = 1; /* don't start with a slash */ |
690 | analyze.imp = imp; |
691 | analyze.fields = ISO_SUSP_SLINK0x0004; |
692 | |
693 | return (cd9660_rrip_loop(isodir, &analyze, rrip_table_getsymname) & |
694 | ISO_SUSP_SLINK0x0004); |
695 | } |
696 | |
697 | static RRIP_TABLE rrip_table_extref[] = { |
698 | { "ER", cd9660_rrip_extref, 0, ISO_SUSP_EXTREF0x0200 }, |
699 | { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT0x0400 }, |
700 | { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP0x1000 }, |
701 | { "", 0, 0, 0 } |
702 | }; |
703 | |
704 | /* |
705 | * Check for Rock Ridge Extension and return offset of its fields. |
706 | * Note: We insist on the ER field. |
707 | */ |
708 | int |
709 | cd9660_rrip_offset(struct iso_directory_record *isodir, struct iso_mnt *imp) |
710 | { |
711 | ISO_RRIP_OFFSET *p; |
712 | ISO_RRIP_ANALYZE analyze; |
713 | |
714 | imp->rr_skip0 = 0; |
715 | p = (ISO_RRIP_OFFSET *)(isodir->name + 1); |
716 | if (bcmp(p, "SP\7\1\276\357", 6)) { |
717 | /* Maybe, it's a CDROM XA disc? */ |
718 | imp->rr_skip0 = 15; |
719 | p = (ISO_RRIP_OFFSET *)((char *)p + 15); |
720 | if (bcmp(p, "SP\7\1\276\357", 6)) |
721 | return (-1); |
722 | } |
723 | |
724 | analyze.imp = imp; |
725 | analyze.fields = ISO_SUSP_EXTREF0x0200; |
726 | if (!(cd9660_rrip_loop(isodir, &analyze, rrip_table_extref) & |
727 | ISO_SUSP_EXTREF0x0200)) |
728 | return (-1); |
729 | |
730 | return (isonum_711(p->skip)); |
731 | } |