|
|
1.1 root 1: /*
2: * Copyright (c) 1993 Atsushi Murai ([email protected])
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * 4. Neither the name of the University nor the names of its contributors
16: * may be used to endorse or promote products derived from this software
17: * without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY Atsushi Murai([email protected])``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: *
31: * isofs_rrip.c,v 1.1 1993/07/19 13:40:06 cgd Exp
32: */
33:
34: #include "param.h"
35: #include "namei.h"
36: #include "buf.h"
37: #include "file.h"
38: #include "vnode.h"
39: #include "mount.h"
40: #include "kernel.h"
41:
42: #include "sys/time.h"
43:
44: #include "iso.h"
45: #include "isofs_node.h"
46: #include "isofs_rrip.h"
47: #include "iso_rrip.h"
48:
49: /*
50: * POSIX file attribute
51: */
52: static int isofs_rrip_attr( p, ana )
53: ISO_RRIP_ATTR *p;
54: ISO_RRIP_ANALYZE *ana;
55: {
56: ana->inode.iso_mode = isonum_731(p->mode_l);
57: ana->inode.iso_uid = (uid_t)isonum_731(p->uid_l);
58: ana->inode.iso_gid = (gid_t)isonum_731(p->gid_l);
59: /* ana->inode.iso_links = isonum_731(p->links_l); */
60: return;
61: }
62:
63: int isofs_rrip_defattr( isodir, ana )
64: struct iso_directory_record *isodir;
65: ISO_RRIP_ANALYZE *ana;
66: {
67: ana->inode.iso_mode = (VREAD|VEXEC|(VREAD|VEXEC)>>3|(VREAD|VEXEC)>>6);
68: ana->inode.iso_uid = (uid_t)0;
69: ana->inode.iso_gid = (gid_t)0;
70: }
71:
72: /*
73: * POSIX device modes
74: */
75: static int isofs_rrip_device( p, ana )
76: ISO_RRIP_DEVICE *p;
77: ISO_RRIP_ANALYZE *ana;
78: {
79: #ifdef NOTYET
80: char buf[3];
81:
82: buf[0] = p->h.type[0];
83: buf[1] = p->h.type[1];
84: buf[2] = 0x00;
85:
86: printf("isofs:%s[%d] high=0x%08x, low=0x%08x\n",
87: buf,
88: isonum_711(p->h.length),
89: isonum_731(p->dev_t_high_l),
90: isonum_731(p->dev_t_low_l)
91: );
92: #endif
93: return;
94: }
95:
96: /*
97: * Symbolic Links
98: */
99: static int isofs_rrip_slink( p, ana )
100: ISO_RRIP_SLINK *p;
101: ISO_RRIP_ANALYZE *ana;
102: {
103: return;
104: }
105:
106: /*
107: * Alternate name
108: */
109: static int isofs_rrip_altname( p, ana )
110: ISO_RRIP_ALTNAME *p;
111: ISO_RRIP_ANALYZE *ana;
112: {
113: return;
114: }
115:
116: /*
117: * Child Link
118: */
119: static int isofs_rrip_clink( p, ana )
120: ISO_RRIP_CLINK *p;
121: ISO_RRIP_ANALYZE *ana;
122: {
123: #ifdef NOTYET
124: char buf[3];
125: buf[0] = p->h.type[0];
126: buf[1] = p->h.type[1];
127: buf[2] = 0x00;
128: printf("isofs:%s[%d] loc=%d\n",
129: buf,
130: isonum_711(p->h.length),
131: isonum_733(p->dir_loc)
132: );
133: #endif
134: ana->inode.iso_cln = isonum_733(p->dir_loc);
135: return;
136: }
137:
138: /*
139: * Parent Link
140: */
141: static int isofs_rrip_plink( p, ana )
142: ISO_RRIP_PLINK *p;
143: ISO_RRIP_ANALYZE *ana;
144: {
145:
146: #ifdef NOTYET
147: char buf[3];
148: buf[0] = p->h.type[0];
149: buf[1] = p->h.type[1];
150: buf[2] = 0x00;
151: printf("isofs:%s[%d] loc=%d\n",
152: buf,
153: isonum_711(p->h.length),
154: isonum_733(p->dir_loc)
155: );
156: #endif
157: ana->inode.iso_pln = isonum_733(p->dir_loc);
158: return;
159: }
160:
161: /*
162: * Relocated directory
163: */
164: static int isofs_rrip_reldir( p, ana )
165: ISO_RRIP_RELDIR *p;
166: ISO_RRIP_ANALYZE *ana;
167: {
168: #ifdef NOTYET
169: char buf[3];
170:
171: buf[0] = p->h.type[0];
172: buf[1] = p->h.type[1];
173: buf[2] = 0x00;
174:
175: printf("isofs:%s[%d]\n",buf, isonum_711(p->h.length) );
176: #endif
177: return;
178: }
179:
180: /*
181: * Time stamp
182: */
183: static void isofs_rrip_tstamp_conv7(pi, pu)
184: char *pi;
185: struct timeval *pu;
186: {
187: int i;
188: int crtime,days;
189: int year,month,day,hour,minute,second,tz;
190:
191: year = pi[0] - 70;
192: month = pi[1];
193: day = pi[2];
194: hour = pi[3];
195: minute = pi[4];
196: second = pi[5];
197: tz = pi[6];
198:
199: if (year < 0) {
200: crtime = 0;
201: } else {
202: int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
203: days = year * 365;
204: if (year > 2)
205: days += (year+2) / 4;
206: for (i = 1; i < month; i++)
207: days += monlen[i-1];
208: if (((year+2) % 4) == 0 && month > 2)
209: days++;
210: days += day - 1;
211: crtime = ((((days * 24) + hour) * 60 + minute) * 60)
212: + second;
213:
214: /* sign extend */
215: if (tz & 0x80)
216: tz |= (-1 << 8);
217:
218: /* timezone offset is unreliable on some disks */
219: if (-48 <= tz && tz <= 52)
220: crtime += tz * 15 * 60;
221: }
222: pu->tv_sec = crtime;
223: pu->tv_usec = 0;
224: }
225:
226:
227: static unsigned isofs_chars2ui( begin, end )
228: unsigned char *begin;
229: unsigned char *end;
230: {
231: unsigned rc=0;
232: int len;
233: int wlen;
234: static int pow[]={ 1, 10, 100, 1000 };
235:
236: len = end - begin;
237: wlen= len;
238: for (; len >= 0; len -- ) {
239: rc += ( *(begin+len) * pow[wlen - len] );
240: }
241: return( rc );
242: }
243:
244: static void isofs_rrip_tstamp_conv17(pi, pu)
245: unsigned char *pi;
246: struct timeval *pu;
247: {
248: unsigned char buf[7];
249:
250: /* year:"0001"-"9999" -> -1900 */
251: buf[0] = (unsigned char)(isofs_chars2ui( &pi[0], &pi[3]) - 1900 );
252:
253: /* month: " 1"-"12" -> 1 - 12 */
254: buf[1] = (unsigned char)isofs_chars2ui( &pi[4], &pi[5]);
255:
256: /* day: " 1"-"31" -> 1 - 31 */
257: buf[2] = isofs_chars2ui( &pi[6], &pi[7]);
258:
259: /* hour: " 0"-"23" -> 0 - 23 */
260: buf[3] = isofs_chars2ui( &pi[8], &pi[9]);
261:
262: /* minute:" 0"-"59" -> 0 - 59 */
263: buf[4] = isofs_chars2ui( &pi[10], &pi[11] );
264:
265: /* second:" 0"-"59" -> 0 - 59 */
266: buf[5] = isofs_chars2ui( &pi[12], &pi[13] );
267:
268: /* difference of GMT */
269: buf[6] = pi[16];
270:
271: isofs_rrip_tstamp_conv7(buf, pu);
272: }
273:
274: static int isofs_rrip_tstamp( p, ana )
275: ISO_RRIP_TSTAMP *p;
276: ISO_RRIP_ANALYZE *ana;
277: {
278: unsigned char *ptime;
279:
280: ptime = p->time;
281:
282: /* Check a format of time stamp (7bytes/17bytes) */
283: if ( !(*p->flags & ISO_SUSP_TSTAMP_FORM17 ) ) {
284: isofs_rrip_tstamp_conv7(ptime, &ana->inode.iso_ctime );
285:
286: if ( *p->flags & ISO_SUSP_TSTAMP_MODIFY )
287: isofs_rrip_tstamp_conv7(ptime+7, &ana->inode.iso_mtime );
288: else
289: ana->inode.iso_mtime = ana->inode.iso_ctime;
290:
291: if ( *p->flags & ISO_SUSP_TSTAMP_ACCESS )
292: isofs_rrip_tstamp_conv7(ptime+14, &ana->inode.iso_atime );
293: else
294: ana->inode.iso_atime = ana->inode.iso_ctime;
295: } else {
296: isofs_rrip_tstamp_conv17(ptime, &ana->inode.iso_ctime );
297:
298: if ( *p->flags & ISO_SUSP_TSTAMP_MODIFY )
299: isofs_rrip_tstamp_conv17(ptime+17, &ana->inode.iso_mtime );
300: else
301: ana->inode.iso_mtime = ana->inode.iso_ctime;
302:
303: if ( *p->flags & ISO_SUSP_TSTAMP_ACCESS )
304: isofs_rrip_tstamp_conv17(ptime+34, &ana->inode.iso_atime );
305: else
306: ana->inode.iso_atime = ana->inode.iso_ctime;
307: }
308: return;
309: }
310:
311: int isofs_rrip_deftstamp( isodir, ana )
312: struct iso_directory_record *isodir;
313: ISO_RRIP_ANALYZE *ana;
314: {
315: isofs_rrip_tstamp_conv7(isodir->date, &ana->inode.iso_ctime );
316: ana->inode.iso_atime = ana->inode.iso_ctime;
317: ana->inode.iso_mtime = ana->inode.iso_ctime;
318: }
319:
320:
321: /*
322: * Flag indicating
323: * Nothing to do....
324: */
325: static int isofs_rrip_idflag( p, ana )
326: ISO_RRIP_IDFLAG *p;
327: ISO_RRIP_ANALYZE *ana;
328: {
329: #ifdef NOTYET
330: char buf[3];
331:
332: buf[0] = p->h.type[0];
333: buf[1] = p->h.type[1];
334: buf[2] = 0x00;
335:
336: printf("isofs:%s[%d] idflag=0x%x\n",
337: buf,
338: isonum_711(p->h.length),
339: p->flags );
340: #endif
341: return;
342: }
343:
344: /*
345: * Extension reference
346: * Nothing to do....
347: */
348: static int isofs_rrip_exflag( p, ana )
349: ISO_RRIP_EXFLAG *p;
350: ISO_RRIP_ANALYZE *ana;
351: {
352: #ifdef NOTYET
353: char buf[3];
354:
355: buf[0] = p->h.type[0];
356: buf[1] = p->h.type[1];
357: buf[2] = 0x00;
358:
359: printf("isofs:%s[%d] exflag=0x%x",
360: buf,
361: isonum_711(p->h.length),
362: p->flags );
363: #endif
364: return;
365: }
366:
367: /*
368: * Unknown ...
369: * Nothing to do....
370: */
371: static int isofs_rrip_unknown( p, ana )
372: ISO_RRIP_EXFLAG *p;
373: ISO_RRIP_ANALYZE *ana;
374: {
375: return;
376: }
377:
378: typedef struct {
379: char type[2];
380: int (*func)();
381: int (*func2)();
382: int result;
383: } RRIP_TABLE;
384:
385: static RRIP_TABLE rrip_table [] = {
386: { 'P', 'X', isofs_rrip_attr, isofs_rrip_defattr, ISO_SUSP_ATTR },
387: { 'T', 'F', isofs_rrip_tstamp, isofs_rrip_deftstamp, ISO_SUSP_TSTAMP },
388: { 'N', 'M', isofs_rrip_altname,0, ISO_SUSP_ALTNAME },
389: { 'C', 'L', isofs_rrip_clink, 0, ISO_SUSP_CLINK },
390: { 'P', 'L', isofs_rrip_plink, 0, ISO_SUSP_PLINK },
391: { 'S', 'L', isofs_rrip_slink, 0, ISO_SUSP_SLINK },
392: { 'R', 'E', isofs_rrip_reldir, 0, ISO_SUSP_RELDIR },
393: { 'P', 'N', isofs_rrip_device, 0, ISO_SUSP_DEVICE },
394: { 'R', 'R', isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG },
395: { 'E', 'R', isofs_rrip_exflag, 0, ISO_SUSP_EXFLAG },
396: { 'S', 'P', isofs_rrip_unknown,0, ISO_SUSP_UNKNOWN },
397: { 'C', 'E', isofs_rrip_unknown,0, ISO_SUSP_UNKNOWN }
398: };
399:
400: int isofs_rrip_analyze ( isodir, analyze )
401: struct iso_directory_record *isodir;
402: ISO_RRIP_ANALYZE *analyze;
403: {
404: register RRIP_TABLE *ptable;
405: register ISO_SUSP_HEADER *phead;
406: register ISO_SUSP_HEADER *pend;
407: int found;
408: int i;
409: char *pwhead;
410: int result;
411:
412: /*
413: * Note: If name length is odd,
414: * it will be padding 1 byte after the name
415: */
416: pwhead = isodir->name + isonum_711(isodir->name_len);
417: if ( !(isonum_711(isodir->name_len) & 0x0001) )
418: pwhead ++;
419: phead = (ISO_SUSP_HEADER *)pwhead;
420: pend = (ISO_SUSP_HEADER *)( (char *)isodir + isonum_711(isodir->length) );
421:
422: result = 0;
423: if ( pend == phead ) {
424: goto setdefault;
425: }
426: /*
427: * Note: "pend" should be more than one SUSP header
428: */
429: while ( pend >= phead + 1) {
430: found = 0;
431: for ( ptable=&rrip_table[0];ptable < &rrip_table[sizeof(rrip_table)/sizeof(RRIP_TABLE)]; ptable ++) {
432: if ( bcmp( phead->type, ptable->type, 2 ) == 0 ) {
433: found = 1;
434: ptable->func( phead, analyze );
435: result |= ptable->result;
436: break;
437: }
438: }
439: if ( found == 0 ) {
440: #ifdef NOTYET
441: printf("isofs: name '");
442: for ( i =0; i < isonum_711(isodir->name_len) ;i++) {
443: printf("%c", *(isodir->name + i) );
444: }
445: printf("'");
446: printf(" - type %c%c [%08x/%08x]...not found\n",
447: phead->type[0], phead->type[1], phead, pend );
448: isofs_hexdump( phead, (int)( (char *)pend - (char *)phead ) );
449: #endif
450: break;
451: }
452:
453: /*
454: * move to next SUSP
455: */
456: phead = (ISO_SUSP_HEADER *) ((unsigned)isonum_711(phead->length) + (char *)phead);
457: }
458:
459: setdefault:
460: /*
461: * If we don't find the Basic SUSP stuffs, just set default value
462: * ( attribute/time stamp )
463: */
464: for ( ptable=&rrip_table[0];ptable < &rrip_table[2]; ptable ++) {
465: if ( ptable->func2 != 0 && !(ptable->result & result) ) {
466: ptable->func2( isodir, analyze );
467: }
468: }
469: return ( result );
470: }
471:
472: /*
473: * Get Alternate Name from 'AL' record
474: * If either no AL recorde nor 0 lenght,
475: * it will be return the translated ISO9660 name,
476: */
477: int isofs_rrip_getname( isodir, outbuf, outlen )
478: struct iso_directory_record *isodir;
479: char *outbuf;
480: int *outlen;
481: {
482: ISO_SUSP_HEADER *phead, *pend;
483: ISO_RRIP_ALTNAME *p;
484: char *pwhead;
485: int found;
486:
487: /*
488: * Note: If name length is odd,
489: * it will be padding 1 byte after the name
490: */
491: pwhead = isodir->name + isonum_711(isodir->name_len);
492: if ( !(isonum_711(isodir->name_len) & 0x0001) )
493: pwhead ++;
494: phead = (ISO_SUSP_HEADER *)pwhead;
495: pend = (ISO_SUSP_HEADER *)( (char *)isodir + isonum_711(isodir->length) );
496:
497: found = 0;
498: if ( pend != phead ) {
499: while ( pend >= phead + 1) {
500: if ( bcmp( phead->type, "NM", 2 ) == 0 ) {
501: found = 1;
502: break;
503: }
504: phead = (ISO_SUSP_HEADER *) ((unsigned)isonum_711(phead->length) + (char *)phead);
505: }
506: }
507: if ( found == 1 ) {
508: p = (ISO_RRIP_ALTNAME *)phead;
509: *outlen = isonum_711( p->h.length ) - sizeof( ISO_RRIP_ALTNAME );
510: bcopy( (char *)( &p->flags + 1 ), outbuf, *outlen );
511: } else {
512: isofntrans(isodir->name, isonum_711(isodir->name_len), outbuf, outlen );
513: if ( *outlen == 1) {
514: switch ( outbuf[0] ) {
515: case 0:
516: outbuf[0] = '.';
517: break;
518: case 1:
519: outbuf[0] = '.';
520: outbuf[1] = '.';
521: *outlen = 2;
522: }
523: }
524: }
525: return( found );
526: }
527:
528: /*
529: * Get Symbolic Name from 'SL' record
530: *
531: * Note: isodir should contains SL record!
532: */
533: int isofs_rrip_getsymname( vp, isodir, outbuf, outlen )
534: struct vnode *vp;
535: struct iso_directory_record *isodir;
536: char *outbuf;
537: int *outlen;
538: {
539: register ISO_RRIP_SLINK_COMPONENT *pcomp;
540: register ISO_SUSP_HEADER *phead, *pend;
541: register ISO_RRIP_SLINK_COMPONENT *pcompe;
542: ISO_RRIP_SLINK *p;
543: char *pwhead;
544: int found;
545: int slash;
546: int wlen;
547:
548: /*
549: * Note: If name length is odd,
550: * it will be padding 1 byte after the name
551: */
552: pwhead = isodir->name + isonum_711(isodir->name_len);
553: if ( !(isonum_711(isodir->name_len) & 0x0001) )
554: pwhead ++;
555: phead = (ISO_SUSP_HEADER *)pwhead;
556: pend = (ISO_SUSP_HEADER *)( (char *)isodir + isonum_711(isodir->length) );
557:
558: found = 0;
559: if ( pend != phead ) {
560: while ( pend >= phead + 1) {
561: if ( bcmp( phead->type, "SL", 2 ) == 0 ) {
562: found = 1;
563: break;
564: }
565: phead = (ISO_SUSP_HEADER *) ((unsigned)isonum_711(phead->length) + (char *)phead);
566: }
567: }
568: if ( found == 0 ) {
569: *outlen = 0;
570: return( found );
571: }
572:
573: p = (ISO_RRIP_SLINK *)phead;
574: pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component;
575: pcompe = (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length));
576:
577: /*
578: * Gathering a Symbolic name from each component with path
579: */
580: *outlen = 0;
581: slash = 0;
582: while ( pcomp < pcompe ) {
583:
584: /* Inserting Current */
585: if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_CURRENT ) {
586: bcopy("./", outbuf+*outlen, 2);
587: *outlen += 2;
588: slash = 0;
589: }
590:
591: /* Inserting Parent */
592: if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_PARENT ) {
593: bcopy("../", outbuf+*outlen, 3);
594: *outlen += 3;
595: slash = 0;
596: }
597:
598: /* Inserting slash for ROOT */
599: if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_ROOT ) {
600: bcopy("/", outbuf+*outlen, 1);
601: *outlen += 1;
602: slash = 0;
603: }
604:
605: /* Inserting a mount point i.e. "/cdrom" */
606: if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_VOLROOT ) {
607: wlen = strlen(vp->v_mount->mnt_stat.f_mntonname);
608: bcopy(vp->v_mount->mnt_stat.f_mntonname,outbuf+*outlen, wlen);
609: *outlen += wlen;
610: slash = 1;
611: }
612:
613: /* Inserting hostname i.e. "tama:" */
614: if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_HOST ) {
615: bcopy(hostname, outbuf+*outlen, hostnamelen);
616: *(outbuf+hostnamelen) = ':';
617: *outlen += (hostnamelen + 1);
618: slash = 0; /* Uuum Should we insert a slash ? */
619: }
620:
621: /* Inserting slash for next component */
622: if ( slash == 1 ) {
623: outbuf[*outlen] = '/';
624: *outlen += 1;
625: slash = 0;
626: }
627:
628: /* Inserting component */
629: wlen = isonum_711(pcomp->clen);
630: if ( wlen != 0 ) {
631: bcopy( pcomp->name, outbuf + *outlen, wlen );
632: *outlen += wlen;
633: slash = 1;
634: }
635:
636: /*
637: * Move to next component...
638: */
639: pcomp = (ISO_RRIP_SLINK_COMPONENT *)((char *)pcomp
640: + sizeof(ISO_RRIP_SLINK_COMPONENT) - 1
641: + isonum_711(pcomp->clen));
642: }
643: return( found );
644: }
645: #ifdef NOTYET
646: /* Hexdump routine for debug*/
647: int isofs_hexdump( p, size )
648: unsigned char *p;
649: int size;
650: {
651: int i,j,k;
652: unsigned char *wp;
653:
654: for ( i = 0; i < size; i += 16 ) {
655: printf("isofs: ");
656: wp = p;
657: k = ( (size - i) > 16 ? 16 : size - i );
658: for ( j =0; j < k; j ++ ){
659: printf("%02x ", *p );
660: p++;
661: }
662: printf(" : ");
663: p = wp;
664: for ( j =0; j < k; j ++ ){
665: if ( (*p > 0x20) && (*p < 0x7f) )
666: printf("%c", *p );
667: else
668: printf(" ");
669: p++;
670: }
671: printf("\n");
672: }
673: printf("\n");
674: }
675: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.