|
|
1.1 root 1: /*
2: *
3: * (c) 2005-2009 Laurent Vivier <[email protected]>
4: *
5: * This file has been copied from EMILE, http://emile.sf.net
6: *
7: * some parts from mkisofs (c) J. Schilling
8: *
9: */
10:
11: #include "libiso9660.h"
12: #include "libopenbios/bindings.h"
13: #include "libc/diskio.h"
14:
15: void iso9660_name(iso9660_VOLUME *volume, struct iso_directory_record *idr, char *buffer)
16: {
17: int j;
18: unsigned char ul, uc;
19:
20: buffer[0] = 0;
21: if (idr->name_len[0] == 1 && idr->name[0] == 0)
22: strcpy(buffer, ".");
23: else if (idr->name_len[0] == 1 && idr->name[0] == 1)
24: strcpy(buffer, "..");
25: else {
26: switch (volume->ucs_level) {
27: case 3:
28: case 2:
29: case 1:
30: /*
31: * Unicode name.
32: */
33:
34: for (j = 0; j < (int)idr->name_len[0] / 2; j++) {
35: ul = idr->name[j*2+1];
36:
37: /*
38: * unicode convertion
39: * up = unls->unls_uni2cs[uh];
40: *
41: * if (up == NULL)
42: * uc = '\0';
43: * else
44: * uc = up[ul];
45: *
46: * we use only low byte
47: */
48:
49: uc = ul;
50:
51: buffer[j] = uc ? uc : '_';
52: }
53: buffer[idr->name_len[0]/2] = '\0';
54: break;
55: case 0:
56: /*
57: * Normal non-Unicode name.
58: */
59: strncpy(buffer, idr->name, idr->name_len[0]);
60: buffer[idr->name_len[0]] = 0;
61: break;
62: default:
63: /*
64: * Don't know how to do these yet. Maybe they are the same
65: * as one of the above.
66: */
67: break;
68: }
69: }
70: }
71:
72: iso9660_VOLUME *iso9660_mount(int fd)
73: {
74: iso9660_VOLUME* volume;
75: struct iso_primary_descriptor *jpd;
76: struct iso_primary_descriptor ipd;
77: int block;
78: int ucs_level = 0;
79:
80: /* read filesystem descriptor */
81:
82: seek_io(fd, 16 * ISOFS_BLOCK_SIZE);
83: read_io(fd, &ipd, sizeof (ipd));
84:
85: /*
86: * High sierra:
87: *
88: * DESC TYPE == 1 (VD_SFS) offset 8 len 1
89: * STR ID == "CDROM" offset 9 len 5
90: * STD_VER == 1 offset 14 len 1
91: */
92:
93: /* High Sierra format ? */
94:
95: if ((((char *)&ipd)[8] == 1) &&
96: (strncmp(&((char *)&ipd)[9], "CDROM", 5) == 0) &&
97: (((char *)&ipd)[14] == 1)) {
98: printk("Incompatible format: High Sierra format\n");
99: return NULL;
100: }
101:
102: /*
103: * ISO 9660:
104: *
105: * DESC TYPE == 1 (VD_PVD) offset 0 len 1
106: * STR ID == "CD001" offset 1 len 5
107: * STD_VER == 1 offset 6 len 1
108: */
109:
110: /* NOT ISO 9660 format ? */
111:
112: if ((ipd.type[0] != ISO_VD_PRIMARY) ||
113: (strncmp(ipd.id, ISO_STANDARD_ID, sizeof (ipd.id)) != 0) ||
114: (ipd.version[0] != 1)) {
115: return NULL;
116: }
117:
118: /* UCS info */
119:
120: block = 16;
121:
122: jpd = (struct iso_primary_descriptor *)
123: malloc(sizeof(struct iso_primary_descriptor));
124: if (jpd == NULL)
125: return NULL;
126:
127: memcpy(jpd, &ipd, sizeof (ipd));
128: while ((uint8_t)jpd->type[0] != ISO_VD_END) {
129:
130: /*
131: * If Joliet UCS escape sequence found, we may be wrong
132: */
133:
134: if (jpd->unused3[0] == '%' &&
135: jpd->unused3[1] == '/' &&
136: (jpd->unused3[3] == '\0' ||
137: jpd->unused3[3] == ' ') &&
138: (jpd->unused3[2] == '@' ||
139: jpd->unused3[2] == 'C' ||
140: jpd->unused3[2] == 'E')) {
141:
142: if (jpd->version[0] != 1)
143: break;
144: }
145:
146: block++;
147: seek_io(fd, block * ISOFS_BLOCK_SIZE);
148: read_io(fd, jpd, sizeof (*jpd));
149: }
150:
151: ucs_level = 0;
152: if (((unsigned char) jpd->type[0] == ISO_VD_END)) {
153: memcpy(jpd, &ipd, sizeof (ipd));
154: } else {
155: switch (jpd->unused3[2]) {
156: case '@':
157: ucs_level = 1;
158: break;
159: case 'C':
160: ucs_level = 2;
161: break;
162: case 'E':
163: ucs_level = 3;
164: break;
165: }
166:
167: if (ucs_level && jpd->unused3[3] == ' ')
168: printk("Warning: Joliet escape sequence uses illegal space at offset 3\n");
169: }
170:
171: volume = (iso9660_VOLUME*)malloc(sizeof(iso9660_VOLUME));
172: if (volume == NULL)
173: return NULL;
174:
175: volume->descriptor = jpd;
176: volume->ucs_level = ucs_level;
177: volume->fd = fd;
178:
179: return volume;
180: }
181:
182: int iso9660_umount(iso9660_VOLUME* volume)
183: {
184: if (volume == NULL)
185: return -1;
186: free(volume->descriptor);
187: free(volume);
188: return 0;
189: }
190:
191: int iso9660_probe(int fd, long long offset)
192: {
193: struct iso_primary_descriptor ipd;
194:
195: seek_io(fd, 16 * ISOFS_BLOCK_SIZE + offset);
196: read_io(fd, &ipd, sizeof (ipd));
197:
198: if ((ipd.type[0] != ISO_VD_PRIMARY) ||
199: (strncmp(ipd.id, ISO_STANDARD_ID, sizeof (ipd.id)) != 0) ||
200: (ipd.version[0] != 1)) {
201: return 0;
202: }
203:
204: return -1;
205: }
206:
207: struct iso_directory_record *iso9660_get_root_node(iso9660_VOLUME* volume)
208: {
209: return (struct iso_directory_record *)volume->descriptor->root_directory_record;
210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.