This source file includes following definitions.
- RRIP_TABLE
- cd9660_rrip_attr
- cd9660_rrip_defattr
- cd9660_rrip_slink
- cd9660_rrip_altname
- cd9660_rrip_defname
- cd9660_rrip_pclink
- cd9660_rrip_reldir
- cd9660_rrip_tstamp
- cd9660_rrip_deftstamp
- cd9660_rrip_device
- cd9660_rrip_idflag
- cd9660_rrip_cont
- cd9660_rrip_stop
- cd9660_rrip_extref
- cd9660_rrip_loop
- cd9660_rrip_analyze
- cd9660_rrip_getname
- cd9660_rrip_getsymname
- cd9660_rrip_offset
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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/file.h>
45 #include <sys/vnode.h>
46 #include <sys/mount.h>
47 #include <sys/kernel.h>
48 #include <sys/stat.h>
49 #include <sys/types.h>
50
51 #include <sys/time.h>
52
53 #include <isofs/cd9660/iso.h>
54 #include <isofs/cd9660/cd9660_extern.h>
55 #include <isofs/cd9660/cd9660_node.h>
56 #include <isofs/cd9660/cd9660_rrip.h>
57 #include <isofs/cd9660/iso_rrip.h>
58
59 typedef struct {
60 char type[2];
61 int (*func)(void *, ISO_RRIP_ANALYZE *);
62 void (*func2)(void *, ISO_RRIP_ANALYZE *);
63 int result;
64 } RRIP_TABLE;
65
66 static int cd9660_rrip_attr(void *, ISO_RRIP_ANALYZE *);
67 static void cd9660_rrip_defattr(void *, ISO_RRIP_ANALYZE *);
68 static int cd9660_rrip_slink(void *, ISO_RRIP_ANALYZE *);
69 static int cd9660_rrip_altname(void *, ISO_RRIP_ANALYZE *);
70 static void cd9660_rrip_defname(void *, ISO_RRIP_ANALYZE *);
71 static int cd9660_rrip_pclink(void *, ISO_RRIP_ANALYZE *);
72 static int cd9660_rrip_reldir(void *, ISO_RRIP_ANALYZE *);
73 static int cd9660_rrip_tstamp(void *, ISO_RRIP_ANALYZE *);
74 static void cd9660_rrip_deftstamp(void *, ISO_RRIP_ANALYZE *);
75 static int cd9660_rrip_device(void *, ISO_RRIP_ANALYZE *);
76 static int cd9660_rrip_idflag(void *, ISO_RRIP_ANALYZE *);
77 static int cd9660_rrip_cont(void *, ISO_RRIP_ANALYZE *);
78 static int cd9660_rrip_stop(void *, ISO_RRIP_ANALYZE *);
79 static int cd9660_rrip_extref(void *, ISO_RRIP_ANALYZE *);
80 static int cd9660_rrip_loop(struct iso_directory_record *,
81 ISO_RRIP_ANALYZE *, RRIP_TABLE *);
82
83
84
85 static int
86 cd9660_rrip_attr(v, ana)
87 void *v;
88 ISO_RRIP_ANALYZE *ana;
89 {
90 ISO_RRIP_ATTR *p = v;
91
92 ana->inop->inode.iso_mode = isonum_733(p->mode);
93 ana->inop->inode.iso_uid = isonum_733(p->uid);
94 ana->inop->inode.iso_gid = isonum_733(p->gid);
95 ana->inop->inode.iso_links = isonum_733(p->links);
96 ana->fields &= ~ISO_SUSP_ATTR;
97 return (ISO_SUSP_ATTR);
98 }
99
100 static void
101 cd9660_rrip_defattr(v, ana)
102 void *v;
103 ISO_RRIP_ANALYZE *ana;
104 {
105 struct iso_directory_record *isodir = v;
106
107
108 printf("RRIP without PX field?\n");
109 cd9660_defattr(isodir, ana->inop, NULL);
110 }
111
112
113
114
115 static int
116 cd9660_rrip_slink(v, ana)
117 void *v;
118 ISO_RRIP_ANALYZE *ana;
119 {
120 ISO_RRIP_SLINK *p = v;
121 register ISO_RRIP_SLINK_COMPONENT *pcomp;
122 register ISO_RRIP_SLINK_COMPONENT *pcompe;
123 int len, wlen, cont;
124 char *outbuf, *inbuf;
125
126 pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component;
127 pcompe =
128 (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length));
129 len = *ana->outlen;
130 outbuf = ana->outbuf;
131 cont = ana->cont;
132
133
134
135
136 for (; pcomp < pcompe;
137 pcomp = (ISO_RRIP_SLINK_COMPONENT *)
138 ((char *)pcomp + ISO_RRIP_SLSIZ + isonum_711(pcomp->clen))) {
139
140 if (!cont) {
141 if (len < ana->maxlen) {
142 len++;
143 *outbuf++ = '/';
144 }
145 }
146 cont = 0;
147
148 inbuf = "..";
149 wlen = 0;
150
151 switch (*pcomp->cflag) {
152
153 case ISO_SUSP_CFLAG_CURRENT:
154
155 wlen = 1;
156 break;
157
158 case ISO_SUSP_CFLAG_PARENT:
159
160 wlen = 2;
161 break;
162
163 case ISO_SUSP_CFLAG_ROOT:
164
165
166 outbuf -= len;
167 len = 0;
168 break;
169
170 case ISO_SUSP_CFLAG_VOLROOT:
171
172
173 outbuf -= len;
174 len = 0;
175 inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname;
176 wlen = strlen(inbuf);
177 break;
178
179 case ISO_SUSP_CFLAG_HOST:
180
181 inbuf = hostname;
182 wlen = hostnamelen;
183 break;
184
185 case ISO_SUSP_CFLAG_CONTINUE:
186 cont = 1;
187
188 case 0:
189
190 wlen = isonum_711(pcomp->clen);
191 inbuf = pcomp->name;
192 break;
193 default:
194 printf("RRIP with incorrect flags?");
195 wlen = ana->maxlen + 1;
196 break;
197 }
198
199 if (len + wlen > ana->maxlen) {
200
201 ana->cont = 1;
202 ana->fields = 0;
203 ana->outbuf -= *ana->outlen;
204 *ana->outlen = 0;
205 return (0);
206 }
207
208 bcopy(inbuf, outbuf, wlen);
209 outbuf += wlen;
210 len += wlen;
211 }
212 ana->outbuf = outbuf;
213 *ana->outlen = len;
214 ana->cont = cont;
215
216 if (!isonum_711(p->flags)) {
217 ana->fields &= ~ISO_SUSP_SLINK;
218 return (ISO_SUSP_SLINK);
219 }
220 return (0);
221 }
222
223
224
225
226 static int
227 cd9660_rrip_altname(v, ana)
228 void *v;
229 ISO_RRIP_ANALYZE *ana;
230 {
231 ISO_RRIP_ALTNAME *p = v;
232 char *inbuf;
233 int wlen;
234 int cont;
235
236 inbuf = "..";
237 wlen = 0;
238 cont = 0;
239
240 switch (*p->flags) {
241 case ISO_SUSP_CFLAG_CURRENT:
242
243 wlen = 1;
244 break;
245
246 case ISO_SUSP_CFLAG_PARENT:
247
248 wlen = 2;
249 break;
250
251 case ISO_SUSP_CFLAG_HOST:
252
253 inbuf = hostname;
254 wlen = hostnamelen;
255 break;
256
257 case ISO_SUSP_CFLAG_CONTINUE:
258 cont = 1;
259
260 case 0:
261
262 wlen = isonum_711(p->h.length) - 5;
263 inbuf = (char *)p + 5;
264 break;
265
266 default:
267 printf("RRIP with incorrect NM flags?\n");
268 wlen = ana->maxlen + 1;
269 break;
270 }
271
272 if ((*ana->outlen += wlen) > ana->maxlen) {
273
274 ana->fields &= ~ISO_SUSP_ALTNAME;
275 ana->outbuf -= *ana->outlen - wlen;
276 *ana->outlen = 0;
277 return (0);
278 }
279
280 bcopy(inbuf, ana->outbuf, wlen);
281 ana->outbuf += wlen;
282
283 if (!cont) {
284 ana->fields &= ~ISO_SUSP_ALTNAME;
285 return (ISO_SUSP_ALTNAME);
286 }
287 return (0);
288 }
289
290 static void
291 cd9660_rrip_defname(v, ana)
292 void *v;
293 ISO_RRIP_ANALYZE *ana;
294 {
295 struct iso_directory_record *isodir = v;
296
297 strlcpy(ana->outbuf, "..", ana->maxlen - *ana->outlen);
298 switch (*isodir->name) {
299 default:
300 isofntrans(isodir->name, isonum_711(isodir->name_len),
301 ana->outbuf, ana->outlen, 1,
302 isonum_711(isodir->flags) & 4, ana->imp->joliet_level);
303 break;
304 case 0:
305 *ana->outlen = 1;
306 break;
307 case 1:
308 *ana->outlen = 2;
309 break;
310 }
311 }
312
313
314
315
316 static int
317 cd9660_rrip_pclink(v, ana)
318 void *v;
319 ISO_RRIP_ANALYZE *ana;
320 {
321 ISO_RRIP_CLINK *p = v;
322
323 *ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift;
324 ana->fields &= ~(ISO_SUSP_CLINK | ISO_SUSP_PLINK);
325 return (*p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK);
326 }
327
328
329
330
331
332 static int
333 cd9660_rrip_reldir(v, ana)
334 void *v;
335 ISO_RRIP_ANALYZE *ana;
336 {
337
338 *ana->outlen = 0;
339 ana->fields = 0;
340 return (ISO_SUSP_RELDIR | ISO_SUSP_ALTNAME | ISO_SUSP_CLINK |
341 ISO_SUSP_PLINK);
342 }
343
344 static int
345 cd9660_rrip_tstamp(v, ana)
346 void *v;
347 ISO_RRIP_ANALYZE *ana;
348 {
349 ISO_RRIP_TSTAMP *p = v;
350 u_char *ptime;
351
352 ptime = p->time;
353
354
355 if (!(*p->flags & ISO_SUSP_TSTAMP_FORM17)) {
356 if (*p->flags & ISO_SUSP_TSTAMP_CREAT)
357 ptime += 7;
358
359 if (*p->flags & ISO_SUSP_TSTAMP_MODIFY) {
360 cd9660_tstamp_conv7(ptime,
361 &ana->inop->inode.iso_mtime);
362 ptime += 7;
363 } else
364 bzero(&ana->inop->inode.iso_mtime,
365 sizeof(struct timespec));
366
367 if (*p->flags & ISO_SUSP_TSTAMP_ACCESS) {
368 cd9660_tstamp_conv7(ptime,
369 &ana->inop->inode.iso_atime);
370 ptime += 7;
371 } else
372 ana->inop->inode.iso_atime =
373 ana->inop->inode.iso_mtime;
374
375 if (*p->flags & ISO_SUSP_TSTAMP_ATTR)
376 cd9660_tstamp_conv7(ptime,
377 &ana->inop->inode.iso_ctime);
378 else
379 ana->inop->inode.iso_ctime =
380 ana->inop->inode.iso_mtime;
381
382 } else {
383 if (*p->flags & ISO_SUSP_TSTAMP_CREAT)
384 ptime += 17;
385
386 if (*p->flags & ISO_SUSP_TSTAMP_MODIFY) {
387 cd9660_tstamp_conv17(ptime,
388 &ana->inop->inode.iso_mtime);
389 ptime += 17;
390 } else
391 bzero(&ana->inop->inode.iso_mtime,
392 sizeof(struct timespec));
393
394 if (*p->flags & ISO_SUSP_TSTAMP_ACCESS) {
395 cd9660_tstamp_conv17(ptime,
396 &ana->inop->inode.iso_atime);
397 ptime += 17;
398 } else
399 ana->inop->inode.iso_atime =
400 ana->inop->inode.iso_mtime;
401
402 if (*p->flags & ISO_SUSP_TSTAMP_ATTR)
403 cd9660_tstamp_conv17(ptime,
404 &ana->inop->inode.iso_ctime);
405 else
406 ana->inop->inode.iso_ctime =
407 ana->inop->inode.iso_mtime;
408
409 }
410 ana->fields &= ~ISO_SUSP_TSTAMP;
411 return (ISO_SUSP_TSTAMP);
412 }
413
414 static void
415 cd9660_rrip_deftstamp(v, ana)
416 void *v;
417 ISO_RRIP_ANALYZE *ana;
418 {
419 struct iso_directory_record *isodir = v;
420
421 cd9660_deftstamp(isodir, ana->inop, NULL);
422 }
423
424
425
426
427 static int
428 cd9660_rrip_device(v, ana)
429 void *v;
430 ISO_RRIP_ANALYZE *ana;
431 {
432 ISO_RRIP_DEVICE *p = v;
433 u_int high, low;
434
435 high = isonum_733(p->dev_t_high);
436 low = isonum_733(p->dev_t_low);
437
438 if (high == 0)
439 ana->inop->inode.iso_rdev = makedev(major(low), minor(low));
440 else
441 ana->inop->inode.iso_rdev = makedev(high, minor(low));
442 ana->fields &= ~ISO_SUSP_DEVICE;
443 return (ISO_SUSP_DEVICE);
444 }
445
446
447
448
449 static int
450 cd9660_rrip_idflag(v, ana)
451 void *v;
452 ISO_RRIP_ANALYZE *ana;
453 {
454 ISO_RRIP_IDFLAG *p = v;
455
456
457 ana->fields &= isonum_711(p->flags) | ~0xff;
458
459 if (ana->fields & ISO_SUSP_RELDIR)
460 return (cd9660_rrip_reldir(p, ana));
461
462 return (ISO_SUSP_IDFLAG);
463 }
464
465
466
467
468 static int
469 cd9660_rrip_cont(v, ana)
470 void *v;
471 ISO_RRIP_ANALYZE *ana;
472 {
473 ISO_RRIP_CONT *p = v;
474
475 ana->iso_ce_blk = isonum_733(p->location);
476 ana->iso_ce_off = isonum_733(p->offset);
477 ana->iso_ce_len = isonum_733(p->length);
478 return (ISO_SUSP_CONT);
479 }
480
481
482
483
484 static int
485 cd9660_rrip_stop(v, ana)
486 void *v;
487 ISO_RRIP_ANALYZE *ana;
488 {
489 return (ISO_SUSP_STOP);
490 }
491
492
493
494
495 static int
496 cd9660_rrip_extref(v, ana)
497 void *v;
498 ISO_RRIP_ANALYZE *ana;
499 {
500 ISO_RRIP_EXTREF *p = v;
501
502 if (isonum_711(p->version) != 1)
503 return (0);
504 if (isonum_711(p->len_id) != 9 &&
505 isonum_711(p->len_id) != 10)
506 return (0);
507 if (isonum_711(p->len_id) == 9 &&
508 bcmp((char *)p + 8, "IEEE_1282", 9))
509 return (0);
510 if (isonum_711(p->len_id) == 10 &&
511 bcmp((char *)p + 8, "IEEE_P1282", 10) &&
512 bcmp((char *)p + 8, "RRIP_1991A", 10))
513 return (0);
514 ana->fields &= ~ISO_SUSP_EXTREF;
515 return (ISO_SUSP_EXTREF);
516 }
517
518
519 static int
520 cd9660_rrip_loop(isodir, ana, table)
521 struct iso_directory_record *isodir;
522 ISO_RRIP_ANALYZE *ana;
523 RRIP_TABLE *table;
524 {
525 register RRIP_TABLE *ptable;
526 register ISO_SUSP_HEADER *phead;
527 register ISO_SUSP_HEADER *pend;
528 struct buf *bp = NULL;
529 char *pwhead;
530 u_char c;
531 int result;
532
533
534
535
536
537 pwhead = isodir->name + isonum_711(isodir->name_len);
538 if (!(isonum_711(isodir->name_len) & 1))
539 pwhead++;
540 isochar(isodir->name, pwhead, ana->imp->joliet_level, &c);
541
542
543 if (c != 0 || isonum_733(isodir->extent) != ana->imp->root_extent)
544 pwhead += ana->imp->rr_skip;
545 else
546 pwhead += ana->imp->rr_skip0;
547
548 phead = (ISO_SUSP_HEADER *)pwhead;
549 pend =
550 (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length));
551
552 result = 0;
553 while (1) {
554 ana->iso_ce_len = 0;
555
556
557
558 while (pend >= phead + 1) {
559 if (isonum_711(phead->version) == 1) {
560 for (ptable = table; ptable->func; ptable++) {
561 if (*phead->type == *ptable->type &&
562 phead->type[1] == ptable->type[1])
563 {
564 result |=
565 ptable->func(phead, ana);
566 break;
567 }
568 }
569 if (!ana->fields)
570 break;
571 }
572 if (result & ISO_SUSP_STOP) {
573 result &= ~ISO_SUSP_STOP;
574 break;
575 }
576
577 if (isonum_711(phead->length) < sizeof(*phead))
578 break;
579
580
581
582
583 phead = (ISO_SUSP_HEADER *)
584 ((char *)phead + isonum_711(phead->length));
585 }
586
587 if (ana->fields && ana->iso_ce_len) {
588 if (ana->iso_ce_blk >= ana->imp->volume_space_size ||
589 ana->iso_ce_off + ana->iso_ce_len >
590 ana->imp->logical_block_size ||
591 bread(ana->imp->im_devvp, ana->iso_ce_blk <<
592 (ana->imp->im_bshift - DEV_BSHIFT),
593 ana->imp->logical_block_size, NOCRED, &bp))
594
595 break;
596 phead =
597 (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off);
598 pend = (ISO_SUSP_HEADER *)
599 ((char *)phead + ana->iso_ce_len);
600 } else
601 break;
602 }
603 if (bp)
604 brelse(bp);
605
606
607
608
609 for (ptable = table; ptable->func2; ptable++)
610 if (!(ptable->result & result))
611 ptable->func2(isodir, ana);
612
613 return (result);
614 }
615
616
617
618
619 static RRIP_TABLE rrip_table_analyze[] = {
620 { "PX", cd9660_rrip_attr, cd9660_rrip_defattr,
621 ISO_SUSP_ATTR },
622 { "TF", cd9660_rrip_tstamp, cd9660_rrip_deftstamp,
623 ISO_SUSP_TSTAMP },
624 { "PN", cd9660_rrip_device, 0,
625 ISO_SUSP_DEVICE },
626 { "RR", cd9660_rrip_idflag, 0,
627 ISO_SUSP_IDFLAG },
628 { "CE", cd9660_rrip_cont, 0,
629 ISO_SUSP_CONT },
630 { "ST", cd9660_rrip_stop, 0,
631 ISO_SUSP_STOP },
632 { "", 0, 0,
633 0 }
634 };
635
636 int
637 cd9660_rrip_analyze(isodir, inop, imp)
638 struct iso_directory_record *isodir;
639 struct iso_node *inop;
640 struct iso_mnt *imp;
641 {
642 ISO_RRIP_ANALYZE analyze;
643
644 analyze.inop = inop;
645 analyze.imp = imp;
646 analyze.fields = ISO_SUSP_ATTR | ISO_SUSP_TSTAMP | ISO_SUSP_DEVICE;
647
648 return (cd9660_rrip_loop(isodir, &analyze, rrip_table_analyze));
649 }
650
651
652
653
654 static RRIP_TABLE rrip_table_getname[] = {
655 { "NM", cd9660_rrip_altname, cd9660_rrip_defname,
656 ISO_SUSP_ALTNAME },
657 { "CL", cd9660_rrip_pclink, 0,
658 ISO_SUSP_CLINK|ISO_SUSP_PLINK },
659 { "PL", cd9660_rrip_pclink, 0,
660 ISO_SUSP_CLINK|ISO_SUSP_PLINK },
661 { "RE", cd9660_rrip_reldir, 0,
662 ISO_SUSP_RELDIR },
663 { "RR", cd9660_rrip_idflag, 0,
664 ISO_SUSP_IDFLAG },
665 { "CE", cd9660_rrip_cont, 0,
666 ISO_SUSP_CONT },
667 { "ST", cd9660_rrip_stop, 0,
668 ISO_SUSP_STOP },
669 { "", 0, 0,
670 0 }
671 };
672
673 int
674 cd9660_rrip_getname(isodir, outbuf, outlen, inump, imp)
675 struct iso_directory_record *isodir;
676 char *outbuf;
677 u_short *outlen;
678 ino_t *inump;
679 struct iso_mnt *imp;
680 {
681 ISO_RRIP_ANALYZE analyze;
682 RRIP_TABLE *tab;
683 u_char c;
684
685 analyze.outbuf = outbuf;
686 analyze.outlen = outlen;
687 analyze.maxlen = NAME_MAX;
688 analyze.inump = inump;
689 analyze.imp = imp;
690 analyze.fields = ISO_SUSP_ALTNAME | ISO_SUSP_RELDIR | ISO_SUSP_CLINK |
691 ISO_SUSP_PLINK;
692 *outlen = 0;
693
694 isochar(isodir->name, isodir->name + isonum_711(isodir->name_len),
695 imp->joliet_level, &c);
696 tab = rrip_table_getname;
697 if (c == 0 || c == 1) {
698 cd9660_rrip_defname(isodir, &analyze);
699
700 analyze.fields &= ~ISO_SUSP_ALTNAME;
701 tab++;
702 }
703
704 return (cd9660_rrip_loop(isodir, &analyze, tab));
705 }
706
707
708
709
710 static RRIP_TABLE rrip_table_getsymname[] = {
711 { "SL", cd9660_rrip_slink, 0, ISO_SUSP_SLINK },
712 { "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG },
713 { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
714 { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
715 { "", 0, 0, 0 }
716 };
717
718 int
719 cd9660_rrip_getsymname(isodir, outbuf, outlen, imp)
720 struct iso_directory_record *isodir;
721 char *outbuf;
722 u_short *outlen;
723 struct iso_mnt *imp;
724 {
725 ISO_RRIP_ANALYZE analyze;
726
727 analyze.outbuf = outbuf;
728 analyze.outlen = outlen;
729 *outlen = 0;
730 analyze.maxlen = MAXPATHLEN;
731 analyze.cont = 1;
732 analyze.imp = imp;
733 analyze.fields = ISO_SUSP_SLINK;
734
735 return (cd9660_rrip_loop(isodir, &analyze, rrip_table_getsymname) &
736 ISO_SUSP_SLINK);
737 }
738
739 static RRIP_TABLE rrip_table_extref[] = {
740 { "ER", cd9660_rrip_extref, 0, ISO_SUSP_EXTREF },
741 { "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
742 { "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
743 { "", 0, 0, 0 }
744 };
745
746
747
748
749
750 int
751 cd9660_rrip_offset(isodir, imp)
752 struct iso_directory_record *isodir;
753 struct iso_mnt *imp;
754 {
755 ISO_RRIP_OFFSET *p;
756 ISO_RRIP_ANALYZE analyze;
757
758 imp->rr_skip0 = 0;
759 p = (ISO_RRIP_OFFSET *)(isodir->name + 1);
760 if (bcmp(p, "SP\7\1\276\357", 6)) {
761
762 imp->rr_skip0 = 15;
763 p = (ISO_RRIP_OFFSET *)((char *)p + 15);
764 if (bcmp(p, "SP\7\1\276\357", 6))
765 return (-1);
766 }
767
768 analyze.imp = imp;
769 analyze.fields = ISO_SUSP_EXTREF;
770 if (!(cd9660_rrip_loop(isodir, &analyze, rrip_table_extref) &
771 ISO_SUSP_EXTREF))
772 return (-1);
773
774 return (isonum_711(p->skip));
775 }