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