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

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