wok view linld/stuff/src/ISO9660.CPP @ rev 20453

Up lz4 (1.8.3)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Oct 05 23:02:32 2018 +0200 (2018-10-05)
parents 008ac2992c52
children 7b15fbf27388
line source
1 #include "crtl.h"
2 #include "crtlx.h"
3 #include "iso9660.h"
4 #define __ROCKRIDGE
6 #define SECTORSZ 2048
7 #define SECTORBITS 11
8 static char buffer[SECTORSZ+512]; // RR overflow
9 struct isostate isostate;
11 static int readsector(const unsigned long *offset)
12 {
13 return (isolseek(offset) != -1
14 && read(isostate.fd, buffer, sizeof(buffer)) >= SECTORSZ);
15 }
17 int isoreset(char *name)
18 {
19 static const unsigned long root = 16UL * 2048;
20 struct isostate *x=&isostate;
21 if (name)
22 //x->fd = open(name, O_RDONLY);
23 x->fd = open(name);
24 if (!readsector(&root) || strhead(buffer+1,"CD001")) {
25 //close(x->fd);
26 return -1;
27 }
28 x->dirofs = (* (unsigned long *) (buffer + 0x9E)) << SECTORBITS;
29 x->dirsize = filesize2dirsize(* (unsigned long *) (buffer + 0xA6));
30 return 0;
31 }
33 int isoreaddir(int restart)
34 {
35 int size;
36 char *p;
37 #ifdef __ROCKRIDGE
38 char *endname;
39 #endif
40 struct isostate *x=&isostate;
42 if (restart) {
43 x->curdirsize = x->dirsize;
44 x->curdirofs = x->dirofs;
45 goto restarted;
46 }
47 if (x->curpos >= SECTORSZ || * (short *) (buffer + x->curpos) == 0) {
48 if (x->curdirsize < DIRSECTORSZ) return -1;
49 restarted:
50 readsector(&x->curdirofs);
51 //x->curdirofs += SECTORSZ;
52 *(int *)((char *) &x->curdirofs+1) += SECTORSZ/256;
53 x->curdirsize -= DIRSECTORSZ;
54 x->curpos &= 0;
55 }
56 p = buffer + x->curpos;
57 if ((size = * (short *) p) == 0)
58 return -1;
59 x->fileofs = (* (unsigned long *) (p + 2)) << SECTORBITS;
60 x->filesize = * (unsigned long *) (p + 10);
61 x->filemod = (p[25] & 2) ? 0040755 : 0100755;
62 //x->filemod = 0100755 - ((p[25] & (char)2) << 13);
63 #ifdef __ROCKRIDGE
64 endname = NULL;
65 // p += 34 + (p[32] & -2); ?
66 p = buffer + 34 + ((p[32] + x->curpos) & -2);
67 do {
68 int len = p[2];
69 switch (* (short *) p) {
70 case 0x4D4E: // NM
71 x->filename = p + 5;
72 endname = p + len;
73 break;
74 case 0x5850: // PX
75 x->filemod = * (short *) (p + 4);
76 break;
77 }
78 p += len;
79 } while (buffer + x->curpos + size - p > 2);
80 if (endname)
81 *endname = 0;
82 else
83 #endif
84 {
85 p = x->filename = buffer + x->curpos + 33;
86 p--;
87 if (((* (short *) p) & 0xFEFF) -1 == 0) {
88 x->filename = "..";
89 if ((* (short *) p) == 1)
90 x->filename++;
91 }
92 else {
93 p += *p; p--;
94 if (* (short *) (p) != 0x313B) {
95 p++; p++; // no ;1 to remove
96 }
97 if (p[-1] == '.') p--;
98 *p = 0;
99 }
100 }
101 x->curpos += size;
102 return 0;
103 }
105 //#define IS_DIR(x)( ((x) & ~0777) == 040000)
106 #define IS_DIR(x)( (char)((x) >> 9) == (char)040)
107 int isoopen(const char *filename)
108 {
109 int restart;
110 char *name, *s, c;
111 char _64bits = cpuhaslm();
112 struct isostate *x=&isostate;
114 retry32:
115 for (s = (char *) filename; *s == '/' ; s++) {
116 isoreset(NULL);
117 }
118 next:
119 for (name = s; *s && *s != '/'; s++);
120 c = *s;
121 *s = 0;
122 for (restart = 1; isoreaddir(restart) == 0; restart = 0) {
123 const char *n = name, *i = x->filename;
124 if (_64bits) {
125 if (strhead(i, n)) continue;
126 n = "64";
127 i += s - name; // strlen(name);
128 }
129 if (strcmp(i, n)) continue;
130 *s++ = c;
131 if (IS_DIR(x->filemod)) {
132 x->dirofs = x->fileofs;
133 x->dirsize = filesize2dirsize(x->filesize);
134 if (c) goto next;
135 }
136 isolseek(&x->fileofs);
137 return 0;
138 }
139 if (_64bits) {
140 _64bits = 0;
141 goto retry32;
142 }
143 return -1;
144 }