wok-6.x view linld/stuff/src/ISO9660.CPP @ rev 19825
linld/tazboot: can boot memtest & ipxe
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sun Mar 05 13:22:08 2017 +0100 (2017-03-05) |
parents | 76087975885f |
children | 008ac2992c52 |
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(const unsigned long *offset)
12 {
13 return (isolseek(offset) != -1
14 && read(isostate.fd, buffer, SECTORSZ) == 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 = * (unsigned long *) (buffer + 0xA6);
30 return 0;
31 }
33 int isoreaddir(int restart)
34 {
35 static char dots[] = "..";
36 int size;
37 char *p;
38 #ifdef __ROCKRIDGE
39 char *endname;
40 #endif
41 struct isostate *x=&isostate;
43 if (restart) {
44 x->curpos = SECTORSZ;
45 x->curdirofs = x->dirofs;
46 x->curdirsize = x->dirsize;
47 }
48 if (x->curpos >= SECTORSZ || * (short *) (buffer + x->curpos) == 0) {
49 if (x->curdirsize < SECTORSZ) return -1;
50 readsector(&x->curdirofs);
51 x->curdirofs += SECTORSZ;
52 x->curdirsize -= SECTORSZ;
53 x->curpos = 0;
54 }
55 p = buffer + x->curpos;
56 size = * (short *) p;
57 if (size == 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 #ifdef __ROCKRIDGE
63 endname = NULL;
64 // p += 34 + (p[32] & -2); ?
65 p = buffer + 34 + ((p[32] + x->curpos) & -2);
66 do {
67 int len = p[2];
68 switch (* (short *) p) {
69 case 0x4D4E: // NM
70 x->filename = p + 5;
71 endname = p + len;
72 break;
73 case 0x5850: // PX
74 x->filemod = * (short *) (p + 4);
75 break;
76 }
77 p += len;
78 }
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 switch (* (short *) p) {
88 case 0x0101:
89 x->filename = dots;
90 break;
91 case 0x0001:
92 x->filename = dots + 1;
93 break;
94 default:
95 p += *p; p--;
96 if (* (short *) (p) != 0x313B) {
97 p++; p++; // no ;1 to remove
98 }
99 if (p[-1] == '.') p--;
100 *p = 0;
101 }
102 }
103 x->curpos += size;
104 return 0;
105 }
107 //#define IS_DIR(x)( ((x) & ~0777) == 040000)
108 #define IS_DIR(x)( (char)((x) >> 9) == (char)040)
109 int isoopen(const char *filename)
110 {
111 int restart;
112 char *name, *s, c;
113 char _64bits = cpuhaslm();
114 struct isostate *x=&isostate;
116 retry32:
117 for (s = (char *) filename; *s == '/' ; s++) {
118 isoreset(NULL);
119 }
120 next:
121 name = s;
122 do s++; while (*s && *s != '/');
123 c = *s;
124 *s = 0;
125 for (restart = 1; isoreaddir(restart) == 0; restart = 0) {
126 const char *n = name, *i = x->filename;
127 if (_64bits) {
128 if (strhead(i, n)) continue;
129 n = "64";
130 i += s - name; // strlen(name);
131 }
132 if (strcmp(i, n)) continue;
133 *s++ = c;
134 if (IS_DIR(x->filemod)) {
135 x->dirofs = x->fileofs;
136 x->dirsize = x->filesize;
137 if (c) goto next;
138 }
139 isolseek(&x->fileofs);
140 return 0;
141 }
142 if (_64bits) {
143 _64bits = 0;
144 goto retry32;
145 }
146 return -1;
147 }