wok annotate linld/stuff/src/ISO9660.CPP @ rev 19571

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