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