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