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.16 2021/03/05 07:10:06 jsg 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 | /*ARGSUSED*/ |
318 | static int |
319 | cd9660_rrip_reldir(void *v, ISO_RRIP_ANALYZE *ana) |
320 | { |
321 | /* special hack to make caller aware of RE field */ |
322 | *ana->outlen = 0; |
323 | ana->fields = 0; |
324 | return (ISO_SUSP_RELDIR0x0040 | ISO_SUSP_ALTNAME0x0008 | ISO_SUSP_CLINK0x0010 | |
325 | ISO_SUSP_PLINK0x0020); |
326 | } |
327 | |
328 | static int |
329 | cd9660_rrip_tstamp(void *v, ISO_RRIP_ANALYZE *ana) |
330 | { |
331 | ISO_RRIP_TSTAMP *p = v; |
332 | u_char *ptime; |
333 | |
334 | ptime = p->time; |
335 | |
336 | /* Check a format of time stamp (7bytes/17bytes) */ |
337 | if (!(*p->flags & ISO_SUSP_TSTAMP_FORM170x80)) { |
338 | if (*p->flags & ISO_SUSP_TSTAMP_CREAT0x01) |
339 | ptime += 7; |
340 | |
341 | if (*p->flags & ISO_SUSP_TSTAMP_MODIFY0x02) { |
342 | cd9660_tstamp_conv7(ptime, |
343 | &ana->inop->inode.iso_mtime); |
344 | ptime += 7; |
345 | } else |
346 | bzero(&ana->inop->inode.iso_mtime,__builtin_bzero((&ana->inop->inode.iso_mtime), (sizeof (struct timespec))) |
347 | sizeof(struct timespec))__builtin_bzero((&ana->inop->inode.iso_mtime), (sizeof (struct timespec))); |
348 | |
349 | if (*p->flags & ISO_SUSP_TSTAMP_ACCESS0x04) { |
350 | cd9660_tstamp_conv7(ptime, |
351 | &ana->inop->inode.iso_atime); |
352 | ptime += 7; |
353 | } else |
354 | ana->inop->inode.iso_atime = |
355 | ana->inop->inode.iso_mtime; |
356 | |
357 | if (*p->flags & ISO_SUSP_TSTAMP_ATTR0x08) |
358 | cd9660_tstamp_conv7(ptime, |
359 | &ana->inop->inode.iso_ctime); |
360 | else |
361 | ana->inop->inode.iso_ctime = |
362 | ana->inop->inode.iso_mtime; |
363 | |
364 | } else { |
365 | if (*p->flags & ISO_SUSP_TSTAMP_CREAT0x01) |
366 | ptime += 17; |
367 | |
368 | if (*p->flags & ISO_SUSP_TSTAMP_MODIFY0x02) { |
369 | cd9660_tstamp_conv17(ptime, |
370 | &ana->inop->inode.iso_mtime); |
371 | ptime += 17; |
372 | } else |
373 | bzero(&ana->inop->inode.iso_mtime,__builtin_bzero((&ana->inop->inode.iso_mtime), (sizeof (struct timespec))) |
374 | sizeof(struct timespec))__builtin_bzero((&ana->inop->inode.iso_mtime), (sizeof (struct timespec))); |
375 | |
376 | if (*p->flags & ISO_SUSP_TSTAMP_ACCESS0x04) { |
377 | cd9660_tstamp_conv17(ptime, |
378 | &ana->inop->inode.iso_atime); |
379 | ptime += 17; |
380 | } else |
381 | ana->inop->inode.iso_atime = |
382 | ana->inop->inode.iso_mtime; |
383 | |
384 | if (*p->flags & ISO_SUSP_TSTAMP_ATTR0x08) |
385 | cd9660_tstamp_conv17(ptime, |
386 | &ana->inop->inode.iso_ctime); |
387 | else |
388 | ana->inop->inode.iso_ctime = |
389 | ana->inop->inode.iso_mtime; |
390 | |
391 | } |
392 | ana->fields &= ~ISO_SUSP_TSTAMP0x0080; |
393 | return (ISO_SUSP_TSTAMP0x0080); |
394 | } |
395 | |
396 | static void |
397 | cd9660_rrip_deftstamp(void *v, ISO_RRIP_ANALYZE *ana) |
398 | { |
399 | struct iso_directory_record *isodir = v; |
400 | |
401 | cd9660_deftstamp(isodir, ana->inop, NULL((void *)0)); |
402 | } |
403 | |
404 | /* |
405 | * POSIX device modes |
406 | */ |
407 | static int |
408 | cd9660_rrip_device(void *v, ISO_RRIP_ANALYZE *ana) |
409 | { |
410 | ISO_RRIP_DEVICE *p = v; |
411 | u_int high, low; |
412 | |
413 | high = isonum_733(p->dev_t_high); |
414 | low = isonum_733(p->dev_t_low); |
415 | |
416 | if (high == 0) |
417 | 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))); |
418 | else |
419 | 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))); |
420 | ana->fields &= ~ISO_SUSP_DEVICE0x0002; |
421 | return (ISO_SUSP_DEVICE0x0002); |
422 | } |
423 | |
424 | /* |
425 | * Flag indicating |
426 | */ |
427 | static int |
428 | cd9660_rrip_idflag(void *v, ISO_RRIP_ANALYZE *ana) |
429 | { |
430 | ISO_RRIP_IDFLAG *p = v; |
431 | |
432 | /* don't touch high bits */ |
433 | ana->fields &= isonum_711(p->flags) | ~0xff; |
434 | /* special handling of RE field */ |
435 | if (ana->fields & ISO_SUSP_RELDIR0x0040) |
436 | return (cd9660_rrip_reldir(p, ana)); |
437 | |
438 | return (ISO_SUSP_IDFLAG0x0100); |
439 | } |
440 | |
441 | /* |
442 | * Continuation pointer |
443 | */ |
444 | static int |
445 | cd9660_rrip_cont(void *v, ISO_RRIP_ANALYZE *ana) |
446 | { |
447 | ISO_RRIP_CONT *p = v; |
448 | |
449 | ana->iso_ce_blk = isonum_733(p->location); |
450 | ana->iso_ce_off = isonum_733(p->offset); |
451 | ana->iso_ce_len = isonum_733(p->length); |
452 | return (ISO_SUSP_CONT0x0400); |
453 | } |
454 | |
455 | /* |
456 | * System Use end |
457 | */ |
458 | static int |
459 | cd9660_rrip_stop(void *v, ISO_RRIP_ANALYZE *ana) |
460 | { |
461 | return (ISO_SUSP_STOP0x1000); |
462 | } |
463 | |
464 | /* |
465 | * Extension reference |
466 | */ |
467 | static int |
468 | cd9660_rrip_extref(void *v, ISO_RRIP_ANALYZE *ana) |
469 | { |
470 | ISO_RRIP_EXTREF *p = v; |
471 | |
472 | if (isonum_711(p->version) != 1) |
473 | return (0); |
474 | if (isonum_711(p->len_id) != 9 && |
475 | isonum_711(p->len_id) != 10) |
476 | return (0); |
477 | if (isonum_711(p->len_id) == 9 && |
478 | bcmp((char *)p + 8, "IEEE_1282", 9)) |
479 | return (0); |
480 | if (isonum_711(p->len_id) == 10 && |
481 | bcmp((char *)p + 8, "IEEE_P1282", 10) && |
482 | bcmp((char *)p + 8, "RRIP_1991A", 10)) |
483 | return (0); |
484 | ana->fields &= ~ISO_SUSP_EXTREF0x0200; |
485 | return (ISO_SUSP_EXTREF0x0200); |
486 | } |
487 | |
488 | |
489 | static int |
490 | cd9660_rrip_loop(struct iso_directory_record *isodir, ISO_RRIP_ANALYZE *ana, |
491 | RRIP_TABLE *table) |
492 | { |
493 | RRIP_TABLE *ptable; |
494 | ISO_SUSP_HEADER *phead; |
495 | ISO_SUSP_HEADER *pend; |
496 | struct buf *bp = NULL((void *)0); |
497 | char *pwhead; |
498 | u_char c; |
499 | int result; |
500 | |
501 | /* |
502 | * Note: If name length is odd, |
503 | * it will be padded by 1 byte after the name |
504 | */ |
505 | pwhead = isodir->name + isonum_711(isodir->name_len); |
506 | if (!(isonum_711(isodir->name_len) & 1)) |
507 | pwhead++; |
508 | isochar(isodir->name, pwhead, ana->imp->joliet_level, &c); |
509 | |
510 | /* If it's not the '.' entry of the root dir obey SP field */ |
511 | if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent) |
512 | pwhead += ana->imp->rr_skip; |
513 | else |
514 | pwhead += ana->imp->rr_skip0; |
515 | |
516 | phead = (ISO_SUSP_HEADER *)pwhead; |
517 | pend = |
518 | (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length)); |
519 | |
520 | result = 0; |
521 | while (1) { |
522 | ana->iso_ce_len = 0; |
523 | /* |
524 | * Note: "pend" should be more than one SUSP header |
525 | */ |
526 | while (pend >= phead + 1) { |
527 | if (isonum_711(phead->version) == 1) { |
528 | for (ptable = table; ptable->func; ptable++) { |
529 | if (*phead->type == *ptable->type && |
530 | phead->type[1] == ptable->type[1]) |
531 | { |
532 | result |= |
533 | ptable->func(phead, ana); |
534 | break; |
535 | } |
536 | } |
537 | if (!ana->fields) |
538 | break; |
539 | } |
540 | if (result & ISO_SUSP_STOP0x1000) { |
541 | result &= ~ISO_SUSP_STOP0x1000; |
542 | break; |
543 | } |
544 | /* plausibility check */ |
545 | if (isonum_711(phead->length) < sizeof(*phead)) |
546 | break; |
547 | /* |
548 | * move to next SUSP |
549 | * Hopefully this works with newer versions, too |
550 | */ |
551 | phead = (ISO_SUSP_HEADER *) |
552 | ((char *)phead + isonum_711(phead->length)); |
553 | } |
554 | |
555 | if (ana->fields && ana->iso_ce_len) { |
556 | if (ana->iso_ce_blk >= ana->imp->volume_space_size || |
557 | ana->iso_ce_off + ana->iso_ce_len > |
558 | ana->imp->logical_block_size || |
559 | bread(ana->imp->im_devvp, ana->iso_ce_blk << |
560 | (ana->imp->im_bshift - DEV_BSHIFT9), |
561 | ana->imp->logical_block_size, &bp)) |
562 | /* what to do now? */ |
563 | break; |
564 | phead = |
565 | (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off); |
566 | pend = (ISO_SUSP_HEADER *) |
567 | ((char *)phead + ana->iso_ce_len); |
568 | } else |
569 | break; |
570 | } |
571 | if (bp) |
572 | brelse(bp); |
573 | /* |
574 | * If we don't find the Basic SUSP stuffs, just set default value |
575 | * (attribute/time stamp) |
576 | */ |
577 | for (ptable = table; ptable->func2; ptable++) |
578 | if (!(ptable->result & result)) |
579 | ptable->func2(isodir, ana); |
580 | |
581 | return (result); |
582 | } |
583 | |
584 | /* |
585 | * Get Attributes. |
586 | */ |
587 | static RRIP_TABLE rrip_table_analyze[] = { |
588 | { "PX", cd9660_rrip_attr, cd9660_rrip_defattr, |
589 | ISO_SUSP_ATTR0x0001 }, |
590 | { "TF", cd9660_rrip_tstamp, cd9660_rrip_deftstamp, |
591 | ISO_SUSP_TSTAMP0x0080 }, |
592 | { "PN", cd9660_rrip_device, 0, |
593 | ISO_SUSP_DEVICE0x0002 }, |
594 | { "RR", cd9660_rrip_idflag, 0, |
595 | ISO_SUSP_IDFLAG0x0100 }, |
596 | { "CE", cd9660_rrip_cont, 0, |
597 | ISO_SUSP_CONT0x0400 }, |
598 | { "ST", cd9660_rrip_stop, 0, |
599 | ISO_SUSP_STOP0x1000 }, |
600 | { "", 0, 0, |
601 | 0 } |
602 | }; |
603 | |
604 | int |
605 | cd9660_rrip_analyze(struct iso_directory_record *isodir, struct iso_node *inop, |
606 | struct iso_mnt *imp) |
607 | { |
608 | ISO_RRIP_ANALYZE analyze; |
609 | |
610 | analyze.inop = inop; |
611 | analyze.imp = imp; |
612 | analyze.fields = ISO_SUSP_ATTR0x0001 | ISO_SUSP_TSTAMP0x0080 | ISO_SUSP_DEVICE0x0002; |
613 | |
614 | return (cd9660_rrip_loop(isodir, &analyze, rrip_table_analyze)); |
615 | } |
616 | |
617 | /* |
618 | * Get Alternate Name. |
619 | */ |
620 | static RRIP_TABLE rrip_table_getname[] = { |
621 | { "NM", cd9660_rrip_altname, cd9660_rrip_defname, |
622 | ISO_SUSP_ALTNAME0x0008 }, |
623 | { "CL", cd9660_rrip_pclink, 0, |
624 | ISO_SUSP_CLINK0x0010|ISO_SUSP_PLINK0x0020 }, |
625 | { "PL", cd9660_rrip_pclink, 0, |
626 | ISO_SUSP_CLINK0x0010|ISO_SUSP_PLINK0x0020 }, |
627 | { "RE", cd9660_rrip_reldir, 0, |
628 | ISO_SUSP_RELDIR0x0040 }, |
629 | { "RR", cd9660_rrip_idflag, 0, |
630 | ISO_SUSP_IDFLAG0x0100 }, |
631 | { "CE", cd9660_rrip_cont, 0, |
632 | ISO_SUSP_CONT0x0400 }, |
633 | { "ST", cd9660_rrip_stop, 0, |
634 | ISO_SUSP_STOP0x1000 }, |
635 | { "", 0, 0, |
636 | 0 } |
637 | }; |
638 | |
639 | int |
640 | cd9660_rrip_getname(struct iso_directory_record *isodir, char *outbuf, |
641 | u_short *outlen, cdino_t *inump, struct iso_mnt *imp) |
642 | { |
643 | ISO_RRIP_ANALYZE analyze; |
644 | RRIP_TABLE *tab; |
645 | u_char c; |
646 | |
647 | analyze.outbuf = outbuf; |
648 | analyze.outlen = outlen; |
649 | analyze.maxlen = NAME_MAX255; |
650 | analyze.inump = inump; |
651 | analyze.imp = imp; |
652 | analyze.fields = ISO_SUSP_ALTNAME0x0008 | ISO_SUSP_RELDIR0x0040 | ISO_SUSP_CLINK0x0010 | |
653 | ISO_SUSP_PLINK0x0020; |
654 | *outlen = 0; |
655 | |
656 | isochar(isodir->name, isodir->name + isonum_711(isodir->name_len), |
657 | imp->joliet_level, &c); |
658 | tab = rrip_table_getname; |
659 | if (c == 0 || c == 1) { |
660 | cd9660_rrip_defname(isodir, &analyze); |
661 | |
662 | analyze.fields &= ~ISO_SUSP_ALTNAME0x0008; |
663 | tab++; |
664 | } |
665 | |
666 | return (cd9660_rrip_loop(isodir, &analyze, tab)); |
667 | } |
668 | |
669 | /* |
670 | * Get Symbolic Link. |
671 | */ |
672 | static RRIP_TABLE rrip_table_getsymname[] = { |
673 | { "SL", cd9660_rrip_slink, 0, ISO_SUSP_SLINK0x0004 }, |
674 | { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG0x0100 }, |
675 | { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT0x0400 }, |
676 | { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP0x1000 }, |
677 | { "", 0, 0, 0 } |
678 | }; |
679 | |
680 | int |
681 | cd9660_rrip_getsymname(struct iso_directory_record *isodir, char *outbuf, |
682 | u_short *outlen, struct iso_mnt *imp) |
683 | { |
684 | ISO_RRIP_ANALYZE analyze; |
685 | |
686 | analyze.outbuf = outbuf; |
687 | analyze.outlen = outlen; |
688 | *outlen = 0; |
689 | analyze.maxlen = MAXPATHLEN1024; |
690 | analyze.cont = 1; /* don't start with a slash */ |
691 | analyze.imp = imp; |
692 | analyze.fields = ISO_SUSP_SLINK0x0004; |
693 | |
694 | return (cd9660_rrip_loop(isodir, &analyze, rrip_table_getsymname) & |
695 | ISO_SUSP_SLINK0x0004); |
696 | } |
697 | |
698 | static RRIP_TABLE rrip_table_extref[] = { |
699 | { "ER", cd9660_rrip_extref, 0, ISO_SUSP_EXTREF0x0200 }, |
700 | { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT0x0400 }, |
701 | { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP0x1000 }, |
702 | { "", 0, 0, 0 } |
703 | }; |
704 | |
705 | /* |
706 | * Check for Rock Ridge Extension and return offset of its fields. |
707 | * Note: We insist on the ER field. |
708 | */ |
709 | int |
710 | cd9660_rrip_offset(struct iso_directory_record *isodir, struct iso_mnt *imp) |
711 | { |
712 | ISO_RRIP_OFFSET *p; |
713 | ISO_RRIP_ANALYZE analyze; |
714 | |
715 | imp->rr_skip0 = 0; |
716 | p = (ISO_RRIP_OFFSET *)(isodir->name + 1); |
717 | if (bcmp(p, "SP\7\1\276\357", 6)) { |
718 | /* Maybe, it's a CDROM XA disc? */ |
719 | imp->rr_skip0 = 15; |
720 | p = (ISO_RRIP_OFFSET *)((char *)p + 15); |
721 | if (bcmp(p, "SP\7\1\276\357", 6)) |
722 | return (-1); |
723 | } |
724 | |
725 | analyze.imp = imp; |
726 | analyze.fields = ISO_SUSP_EXTREF0x0200; |
727 | if (!(cd9660_rrip_loop(isodir, &analyze, rrip_table_extref) & |
728 | ISO_SUSP_EXTREF0x0200)) |
729 | return (-1); |
730 | |
731 | return (isonum_711(p->skip)); |
732 | } |