wok view linld/stuff/src/ISO9660.CPP @ rev 19571
linld: large image support with VCPI
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Thu Dec 22 21:06:17 2016 +0100 (2016-12-22) |
parents | 31c5cbbd9380 |
children | 76087975885f |
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];
9 struct isostate isostate;
11 static int readsector(unsigned long offset)
12 {
13 return (isolseek(offset) != -1
14 && read(isostate.fd, buffer, SECTORSZ) == SECTORSZ);
15 }
17 int isoread(char *data, unsigned size)
18 {
19 int get, n;
21 struct isostate *x=&isostate;
22 if (size > x->filesize)
23 size = x->filesize;
24 if (isolseek(x->fileofs) == -1)
25 return -1;
26 for (get = size; get; get -= n, data += n) {
27 n = read(x->fd,data,get);
28 if (n < 0)
29 return n;
30 if (n == 0)
31 break;
32 x->fileofs += n;
33 x->filesize -= n;
34 }
35 return size - get;
36 }
38 int isoreset(char *name)
39 {
40 struct isostate *x=&isostate;
41 if (name)
42 //x->fd = open(name, O_RDONLY);
43 x->fd = open(name);
44 if (!readsector(16UL * 2048) || strhead(buffer+1,"CD001")) {
45 //close(x->fd);
46 return -1;
47 }
48 x->dirofs = * (unsigned long *) (buffer + 0x9E);
49 x->dirofs <<= SECTORBITS;
50 x->dirsize = * (unsigned long *) (buffer + 0xA6);
51 return 0;
52 }
54 int isoreaddir(int restart)
55 {
56 static char dots[] = "..";
57 int size, n;
58 #ifdef __ROCKRIDGE
59 char *endname;
60 #endif
61 struct isostate *x=&isostate;
63 if (restart) {
64 x->curdirofs = x->dirofs;
65 x->curdirsize = x->dirsize;
66 x->curpos = SECTORSZ;
67 }
68 if (x->curpos >= SECTORSZ || * (short *) (buffer + x->curpos) == 0) {
69 if (x->curdirsize < SECTORSZ) return -1;
70 readsector(x->curdirofs);
71 x->curdirofs += SECTORSZ;
72 x->curdirsize -= SECTORSZ;
73 x->curpos = 0;
74 }
75 size = * (short *) (buffer + x->curpos);
76 if (size == 0)
77 return -1;
78 x->fileofs = (* (unsigned long *) (buffer + x->curpos + 2)) << SECTORBITS;
79 x->filesize = * (unsigned long *) (buffer + x->curpos + 10);
80 x->filemod = (buffer[x->curpos + 25] & 2) ? 0040755 : 0100755;
81 #ifdef __ROCKRIDGE
82 endname = NULL;
83 n = (buffer[x->curpos + 32] + x->curpos + 34) & -2;
84 do {
85 int len = buffer[n + 2];
86 switch (* (short *) (buffer + n)) {
87 case 0x4D4E: // NM
88 x->filename = buffer + n + 5;
89 endname = buffer + n + len;
90 break;
91 case 0x5850: // PX
92 x->filemod = * (short *) (buffer + n + 4);
93 break;
94 }
95 n += len;
96 }
97 while (n + 2 < x->curpos + size);
98 if (endname)
99 *endname = 0;
100 else
101 #endif
102 {
103 x->filename = buffer + x->curpos + 33;
104 switch (* (short *) (x->filename - 1)) {
105 case 0x0101:
106 x->filename = dots;
107 break;
108 case 0x0001:
109 x->filename = dots + 1;
110 break;
111 default:
112 n = x->filename[-1];
113 if (* (short *) (x->filename + n - 2) == 0x313B)
114 n -= 2; // remove ;1
115 if (x->filename[n - 1] == '.') n--;
116 x->filename[n] = 0;
117 }
118 }
119 x->curpos += size;
120 return 0;
121 }
123 #define IS_DIR(x)( ((x) & ~0777) == 040000)
124 int isoopen(char *filename)
125 {
126 int restart;
127 char *name, *s, c;
128 int _64bits = cpuhaslm();
129 struct isostate *x=&isostate;
131 retry32:
132 name = filename;
133 while (*name == '/') {
134 name++;
135 isoreset(NULL);
136 }
137 s = name;
138 while (1) {
139 while (*s && *s != '/') s++;
140 c = *s;
141 *s = 0;
142 for (restart = 1; isoreaddir(restart) == 0; restart = 0) {
143 char *n = name, *i = x->filename;
144 if (_64bits) {
145 int len = strlen(name);
146 if (strhead(x->filename, name)) continue;
147 n = "64";
148 i += len;
149 }
150 if (strcmp(n, i)) continue;
151 if (IS_DIR(x->filemod)) {
152 x->dirofs = x->fileofs;
153 x->dirsize = x->filesize;
154 if (c) {
155 *s++ = c;
156 name = s;
157 goto next;
158 }
159 }
160 isolseek(x->fileofs);
161 return 0;
162 }
163 if (_64bits) {
164 _64bits = 0;
165 *s = c;
166 goto retry32;
167 }
168 return -1;
169 next: ;
170 }
171 }