wok-current annotate linld/stuff/src/ISO9660.CPP @ rev 19515

linld: multi initrd support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Nov 22 21:19:01 2016 +0100 (2016-11-22)
parents
children 31c5cbbd9380
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 }