wok annotate syslinux/stuff/iso2exe/iso9660.c @ rev 14266

syslinux/iso2exe: add partition table
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon Apr 01 17:47:04 2013 +0200 (2013-04-01)
parents
children 6aed6fc5819d
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 }