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