From 551a53e1b9c0fb7699e4e44e273d9f57111a1c21 Mon Sep 17 00:00:00 2001
From: pixel <pixel>
Date: Tue, 19 Oct 2004 15:58:41 +0000
Subject: Fixing cd-tool bugs.

---
 lib/cdutils.cpp    | 1882 ++++++++++++++---------------
 lib/isobuilder.cpp |   10 +-
 lib/luacd.cpp      | 3317 ++++++++++++++++++++++++++--------------------------
 3 files changed, 2607 insertions(+), 2602 deletions(-)

(limited to 'lib')

diff --git a/lib/cdutils.cpp b/lib/cdutils.cpp
index d9efe68..2d9263b 100644
--- a/lib/cdutils.cpp
+++ b/lib/cdutils.cpp
@@ -1,941 +1,941 @@
-/*
- *  PSX-Tools Bundle Pack
- *  Copyright (C) 2002-2003 Nicolas "Pixel" Noble
- * 
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/* $Id: cdutils.cpp,v 1.30 2004-07-30 00:49:47 pixel Exp $ */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "generic.h"
-#include "cdutils.h"
-#include "Output.h"
-
-const long sec_sizes[7] =  {0, 2048, 2336, 2048, 2324, 2352, 2352};
-const long sec_offsts[7] = {0,   16,   16,   24,   24,    0,    0};
-const String sec_modes[7] = {"MODE 0 (empty)", "MODE 1", "MODE 2", "MODE 2 FORM 1", "MODE 2 FORM 2", "Raw", "Autodetect"};
-
-cdutils::cdutils(Handle * r, Handle * w) : rootDir(0), f_iso_r(r), f_iso_w(w), ppf_file(0), pt1(-1), pt2(-1), snum(0), ptl(0), root(0) {}
-
-cdutils::~cdutils() {
-    if (ppf_file)
-	delete ppf_file;
-    free(rootDir);
-}
-
-unsigned char cdutils::from_BCD(unsigned char x) {
-    return ((x & 0xf) + ((x & 0xf0) >> 4) * 10);
-}
-
-unsigned char cdutils::to_BCD(unsigned char x) {
-    return ((x / 10) << 4) | (x % 10);
-}
-
-bool cdutils::is_valid_BCD(unsigned char x) {
-    return (((x & 15) < 10) && ((x >> 4) < 10));
-}
-
-unsigned long cdutils::from_MSF(unsigned char m, unsigned char s, unsigned char f, unsigned long start) {
-    return (from_BCD(m) * 60 + from_BCD(s)) * 75 + from_BCD(f) - start;
-}
-
-unsigned long cdutils::from_MSF(unsigned long msf, unsigned long start) {
-    unsigned char
-    f = msf & 0xff,
-    s = (msf >> 8) & 0xff,
-    m = (msf >> 16) & 0xff;
-    
-    return from_MSF(m, s, f, start);
-}
-
-void cdutils::to_MSF(int sect, unsigned char & m, unsigned char & s, unsigned char & f, unsigned long start) {
-    sect += start;
-    f = to_BCD(sect % 75);
-    sect /= 75;
-    s = to_BCD(sect % 60);
-    m = to_BCD(sect / 60);
-}
-
-unsigned long cdutils::to_MSF(int sect, unsigned long start) {
-    unsigned char m, s, f;
-    to_MSF(sect, m, s, f, start);
-    return f | (s << 8) | (m << 16);
-}
-
-Handle * cdutils::open_ppf(String ppf, String comment) throw (GeneralException) {
-    int i, l;
-
-    if (ppf_file)
-	throw GeneralException("Tried to open_ppf() while already opened.");
-    ppf_file = new Output(ppf);
-    ppf_file->write("PPF20\001", 6);
-    
-    l = comment.strlen();
-    if (l >= 50) {
-	ppf_file->write(comment.to_charp(), 50);
-    } else {
-	char * t = " ";
-	ppf_file->write(comment.to_charp(), l);
-	for (i = l; i < 50; i++) {
-	    ppf_file->write(t, 1);
-	}
-    }
-    
-    l = f_iso_r->GetSize();
-    ppf_file->write(&l, sizeof(l));
-    
-    f_iso_r->seek(0x9320, SEEK_SET);
-//    copy(f_iso_r, ppf_file, 1024);
-    return ppf_file;
-}
-
-void cdutils::write_ppf(Byte * old_sec, Byte * new_sec, int sec_num) {
-    int i, l = 0, o;
-    
-    for (i = 0; i < 2352; i++) {
-	if (old_sec[i] == new_sec[i]) {
-	    if (l != 0) {
-		o = 2352 * sec_num + i;
-		ppf_file->write(&o, sizeof(o));
-		ppf_file->write(&l, 1);
-		ppf_file->write(new_sec + i - l - 1, l);
-		l = 0;
-	    }
-	} else {
-	    l++;
-	    if (l == 255) {
-		o = 2352 * sec_num + i;
-		ppf_file->write(&o, 4);
-		ppf_file->write(&l, 1);
-		ppf_file->write(new_sec + i - 255, 255);
-		l = 0;
-	    }
-	}
-    }
-}
-
-void cdutils::close_ppf() throw (GeneralException) {
-    if (ppf_file) {
-	delete ppf_file;
-	ppf_file = 0;
-    } else {
-	throw GeneralException("Tried to close_ppf() without previous opening");
-    }
-}
-
-void cdutils::set_iso_w(Handle * w) {
-    if (!f_iso_w)
-	f_iso_w = w;
-}
-
-String cdutils::format_date(String input) {
-    String output;
-    
-    output  = input.extract(6, 7) + '/';
-    output += input.extract(4, 5) + '/';
-    output += input.extract(0, 3) + ' ';
-    output += input.extract(8, 9) + ':';
-    output += input.extract(10, 11) + ':';
-    output += input.extract(12, 13) + '.';
-    output += input.extract(14, 15);
-    output += String("").set("%+3.1f", ((float) (*((input.to_charp()) + 16))) / 4);
-    return output;
-}
-
-Uint16 cdutils::swap_word(Uint16 i) {
-    return (i >> 8) | (i << 8);
-}
-
-Uint32 cdutils::swap_dword(Uint32 i) {
-    return (i >> 24) | ((i >> 8) & 0x0000ff00) | ((i << 8) & 0x00ff0000) | (i << 24);
-}
-
-int cdutils::guess_type(int number) {
-    Byte header[24];
-    
-    if (number >= 0) {
-	sector_seek(number);
-    }
-    
-    f_iso_r->read(header, 24);
-    f_iso_r->seek(-24, SEEK_CUR);
-    if (header[15] == 1) {
-	return MODE_1;
-    } else if (header[15] == 2) {
-	if (*((unsigned long *) &(header[16])) == *((unsigned long *) &(header[20]))) {
-	    if ((header[16] == 0) && (header[17] == 0) && (header[19] == 0)) {
-		if (header[18] & 0x20) {
-		    return MODE_2_FORM_2;
-		} else {
-		    return MODE_2_FORM_1;
-		}
-	    }
-	}
-	return MODE_2;
-    }
-    
-    return MODE_0;
-}
-
-void cdutils::sector_seek(long sector) {
-    f_iso_r->seek(2352 * sector);
-    if (f_iso_w)
-        f_iso_w->seek(2352 * sector);
-}
-
-long cdutils::read_sector(Byte * buffer, int type, int number) {
-    if (number >= 0) {
-	sector_seek(number);
-    }
-    
-    if (type == GUESS) {
-	type = guess_type();
-    }
-    
-    f_iso_r->seek(sec_offsts[type], SEEK_CUR);
-    f_iso_r->read(buffer, sec_sizes[type]);
-    f_iso_r->seek(2352 - sec_offsts[type] - sec_sizes[type], SEEK_CUR);
-    return sec_sizes[type];
-}
-
-void cdutils::read_datas(Byte * buffer, long size, int type, int number) {
-    Byte sector[2352];
-    int i, n, reste;
-    
-    if (type == GUESS) {
-	type = guess_type(number);
-    }
-    
-    n = size / sec_sizes[type];
-    reste = size - n * sec_sizes[type];
-    
-    sector_seek(number);
-    for (i = 0; i < n; i++) {
-	read_sector(buffer + i * sec_sizes[type], type);
-    }
-    
-    if (reste) {
-	read_sector(sector, type);
-	bcopy((char *) sector, (char *) (buffer + n * sec_sizes[type]), reste);
-    }
-}
-
-void cdutils::read_file(Handle * file, long size, int type, int number) {
-    Byte sector[2352];
-    int i, n, reste;
-    
-    if (type == GUESS) {
-	type = guess_type(number);
-    }
-    
-    n = size / sec_sizes[type];
-    reste = size - n * sec_sizes[type];
-    
-    for (i = 0; i < n; i++) {
-	sector_seek(number + i);
-	try {
-	    read_sector(sector, type);
-	}
-	catch(...) {
-	    memset(sector, 0, 2352);
-	}
-	file->write(sector, sec_sizes[type]);
-    }
-    
-    sector_seek(number + n);
-    if (reste) {
-	try {
-	    read_sector(sector, type);
-	}
-	catch(...) {
-	    memset(sector, 0, 2352);
-	}
-	file->write(sector, reste);
-    }
-}
-
-void cdutils::write_sector(Byte * buffer, int type, int number) throw (GeneralException) {
-    Byte old_sector[2352], new_sector[2352];
-
-    if (type == GUESS) {
-	type = guess_type(number);
-    }
-
-    if (number >= 0) {
-	sector_seek(number);
-    } else {
-	number = f_iso_r->tell() / 2352;
-    }
-    
-    f_iso_r->read(old_sector, 2352);
-    
-    yazedc_o.minute = old_sector[12];
-    yazedc_o.second = old_sector[13];
-    yazedc_o.frame = old_sector[14];
-    
-    bcopy((char *) old_sector, (char *) new_sector, 2532);
-    bcopy((char *) buffer, (char *) new_sector + sec_offsts[type], sec_sizes[type]);
-    
-    yazedc_o.do_encode_L2(new_sector, type, 0);
-    if (f_iso_w) {
-	f_iso_w->write(new_sector, 2352);
-    } else if (ppf_file) {
-	write_ppf(old_sector, new_sector, number);
-    } else {
-	throw GeneralException("No writing method for iso file");
-    }
-}
-
-void cdutils::write_datas(Byte * buffer, long size, int type, int number) {
-    long nbsectors, i;
-    unsigned char sector[2352];
-
-    if (type == GUESS) {
-	type = guess_type(number);
-    }
-
-    if (number >= 0) {
-	sector_seek(number);
-    }
-    
-    nbsectors = size / sec_sizes[type];
-    
-    for (i = 0; i < nbsectors; i++) {
-	write_sector(buffer + i * sec_sizes[type], type, number + i);
-    }
-
-    if (size % sec_sizes[type]) {
-	memset(sector, 0, 2352);
-	bcopy((char *) (buffer + i * sec_sizes[type]), (char *) sector, size % sec_sizes[type]);
-	write_sector(sector, type, number + i);
-    }
-}
-
-void cdutils::write_file(Handle * file, long size, int type, int number) {
-    long nbsectors, i;
-    unsigned char buffer[2352];
-    
-    if (type == GUESS) {
-	type = guess_type(number);
-    }
-    
-    if (number >= 0) {
-	sector_seek(number);
-    }
-    
-    if (size < 0)
-        size = file->GetSize();
-    nbsectors = size / sec_sizes[type];
-    
-    if (size % sec_sizes[type]) {
-	nbsectors++;
-    }
-    
-    for (i = 0; i < nbsectors; i++) {
-	memset(buffer, 0, 2352);
-	size = file->read(buffer, sec_sizes[type]);
-	write_sector(buffer, type);
-    }
-}
-
-void cdutils::create_sector(int type, int number, bool eof) throw (GeneralException) {
-    Byte sector[2352];
-    if (!f_iso_w)
-	throw GeneralException("Can't create sector: ISO not in write mode");
-    
-    to_MSF(number, yazedc_o.minute, yazedc_o.second, yazedc_o.frame);
-    memset(sector, 0, 2352);
-    if ((type == MODE2_FORM1) || (type == MODE2_FORM2)) {
-	sector[16] = sector[20] = 0;  // File Number
-	sector[17] = sector[21] = 0;  // Channel Number
-	sector[18] = sector[22] = 8 | (eof ? 129 : 0) |
-	                          (type == MODE2_FORM2 ? 32 : 0);
-	sector[19] = sector[23] = 0;  // Coding Info
-    }
-    yazedc_o.do_encode_L2(sector, type, 0);
-
-    f_iso_w->seek(2352 * number);
-    
-    f_iso_w->write(sector, 2352);
-    
-    sector_seek(number);
-}
-
-void cdutils::show_head_entry(void) {
-    printm(M_BARE, "Sector   Size        Date       Time       Flags  Name           XA flags\n");
-}
-
-int cdutils::show_entry(struct DirEntry * dir) {
-    char pbuf[200], pad;
-    int s;
-    if ((!dir) || (!dir->R)) {
-	return 1;
-    }
-    
-    strncpy(pbuf, dir->id, dir->N);
-    pbuf[dir->N] = 0;
-    if ((dir->N == 1) && (pbuf[0] == 0)) {
-	strcpy(pbuf, ".");
-    }
-    if ((dir->N == 1) && (pbuf[0] == 1)) {
-	strcpy(pbuf, "..");
-    }
-
-    s = 33 + dir->N;
-    if (s & 1) {
-        s++;
-        pad = 1;
-    } else {
-        pad = 0;
-    }
-    if (s != dir->R) {
-        if ((s + 14) == dir->R) {
-            Byte * p;
-            p = (Byte *) dir->id + dir->N + pad;
-            if ((p[6] == 'X') && (p[7] == 'A')) {
-                sprintf(pbuf, "%-14s %c%c%c%c%c", pbuf,
-                    p[4] & 0x80 ? 'd' : '-',
-                    p[4] & 0x40 ? 'a' : '-',
-                    p[4] & 0x20 ? 's' : '-',
-                    p[4] & 0x10 ? 'x' : '-',
-                    p[4] & 0x08 ? 'f' : '-');
-            }
-        }
-    }
-
-    if (dir->Year < 70)
-	dir->Year += 100;
-
-    printm(M_BARE, "%6i %9i %2i/%02i/%04i %2i:%02i:%02i%+03.1f %c%c%c%c%c%c%c%c %s\n",
-           dir->Sector, dir->Size, dir->Day, dir->Month, dir->Year + 1900, dir->Hour, dir->Minute, dir->Second, ((float) dir->Offset) / 4,
-           dir->Flags &  1 ? 'H' : '-', dir->Flags &  2 ? 'D' : '-', dir->Flags &  4 ? 'A' : '-', dir->Flags &   8 ? 'R' : '-',
-	   dir->Flags & 16 ? 'P' : '-', dir->Flags & 32 ? '1' : '-', dir->Flags & 64 ? '1' : '-', dir->Flags & 128 ? 'C' : '-', pbuf);
-    return dir->R;
-}
-
-int cdutils::show_dir(struct DirEntry * dir) {
-    unsigned int ptr;
-    Byte * buffer;
-    
-    if (!(dir->Flags & 2)) {
-	return 0;
-    }
-    
-    buffer = (Byte *) malloc(dir->Size);
-    read_datas(buffer, dir->Size, GUESS, dir->Sector);
-    
-    ptr = 0;
-    while(ptr < dir->Size) {
-	ptr += show_entry((struct DirEntry *) &(buffer[ptr]));
-    }
-    
-    free(buffer);
-    return 1;
-}
-
-struct cdutils::DirEntry cdutils::find_dir_entry(struct DirEntry * dir, String name) {
-    unsigned int ptr, size;
-    unsigned char * buffer;
-    struct DirEntry r = {0, 0, 0, 0, 0};
-    
-    if (!(dir->Flags & 2)) {
-	return r;
-    }
-    
-    buffer = (unsigned char *) malloc(size = dir->Size);
-    read_datas(buffer, dir->Size, GUESS, dir->Sector);
-    
-    ptr = 0;
-    while(ptr < size) {
-	dir = (struct DirEntry *) &(buffer[ptr]);
-	if (!dir->R) {
-	    ptr++;
-	} else {
-	    if (!strncmp(name.to_charp(), (char *) &(dir->id), dir->N)) {
-		r = *dir;
-	    }
-	    ptr += dir->R;
-	}
-    }
-
-    free(buffer);
-    return r;
-}
-
-struct cdutils::DirEntry * cdutils::find_dir_entry(Byte ** bufout, struct cdutils::DirEntry * dir, String name) {
-    unsigned int ptr, size;
-    Byte * buffer;
-    struct DirEntry * rdir = 0;
-    *bufout = 0;
-    
-    if (!(dir->Flags & 2)) {
-	return 0;
-    }
-    
-    buffer = (Byte *) malloc(size = dir->Size);
-    read_datas(buffer, dir->Size, GUESS, dir->Sector);
-    
-    ptr = 0;
-    while(ptr < size) {
-	dir = (struct DirEntry *) &(buffer[ptr]);
-	if (!dir->R) {
-	    ptr++;
-	} else {
-	    if (!strncmp(name.to_charp(), (char *) &(dir->id), dir->N)) {
-		rdir = dir;
-	    }
-	    ptr += dir->R;
-	}
-    }
-
-    if (rdir && rdir->R) {
-        free(*bufout);
-	*bufout = buffer;
-    } else {
-	free(buffer);
-        rdir = 0;
-    }
-    return rdir;
-}
-
-int cdutils::show_iso_infos() {
-    char buffer[2048];
-    char pbuff[130];
-    short int s, nogood = 0;
-
-    read_sector((Byte *) buffer, GUESS, 16);
-
-    printm(M_BARE, "Sector guessed mode : " + sec_modes[guess_type(16)] + "\n");
-    printm(M_BARE, "offset-size-info    : contents\n");
-    printm(M_BARE, "    0 -   1-  1     : %i\n", buffer[0]);
-    memcpy(pbuff, buffer + 1, 5);
-    pbuff[5] = 0;
-    printm(M_BARE, "    1 -   5-`CD001' : %s\n", pbuff);
-    printm(M_BARE, "    6 -   2-  1     : %i\n", s = *((short int *) &(buffer[6])));
-    printm(M_BARE, "(*this was the signature*)\n");
-    if (buffer[0] != 1) nogood = 1;
-    if (strcmp(pbuff, "CD001")) nogood = 1;
-    if (s != 1) nogood = 1;
-    
-    if (nogood) {
-	printm(M_BARE, "Not a valid iso9660 file.\n");
-	return 0;
-    }
-    
-    memcpy(pbuff, buffer + 8, 32);
-    pbuff[32] = 0;
-    printm(M_BARE, "    8 -  32- SYSID  : %s\n", pbuff);
-    memcpy(pbuff, buffer + 40, 32);
-    pbuff[32] = 0;
-    printm(M_BARE, "   40 -  32- VOLID  : %s\n", pbuff);
-    printm(M_BARE, "   80 -   8- SNum   : %li\n", *((long int *) &(buffer[80])));
-    printm(M_BARE, "  120 -   4- VOLSiz : %i\n", *((short int *) &(buffer[120])));
-    printm(M_BARE, "  124 -   4- VOLNum : %i\n", *((short int *) &(buffer[124])));
-    printm(M_BARE, "  128 -   4- SSize  : %i\n", *((short int *) &(buffer[128])));
-    printm(M_BARE, "  132 -   8- PSize  : %li\n", *((long int *) &(buffer[132])));
-    printm(M_BARE, "  140 -   4- 1SLPath: %i\n", *((short int *) &(buffer[140])));
-    printm(M_BARE, "  144 -   4- 2SLPath: %i\n", *((short int *) &(buffer[144])));
-    printm(M_BARE, "  148 -   4- 1SBPath: %i\n", swap_word(*((short int *) &(buffer[150]))));
-    printm(M_BARE, "  152 -   4- 2SBPath: %i\n", swap_word(*((short int *) &(buffer[154]))));
-    memcpy(pbuff, buffer + 190, 128);
-    pbuff[128] = 0;
-    printm(M_BARE, "  190 - 128- VStId  : %s\n", pbuff);
-    memcpy(pbuff, buffer + 318, 128);
-    pbuff[128] = 0;
-    printm(M_BARE, "  318 - 128- PubId  : %s\n", pbuff);
-    memcpy(pbuff, buffer + 446, 128);
-    pbuff[128] = 0;
-    printm(M_BARE, "  446 - 128- DPrId  : %s\n", pbuff);
-    memcpy(pbuff, buffer + 574, 128);
-    pbuff[128] = 0;
-    printm(M_BARE, "  574 - 128- AppId  : %s\n", pbuff);
-    memcpy(pbuff, buffer + 702, 37);
-    pbuff[37] = 0;
-    printm(M_BARE, "  702 -  37- CpyFile: %s\n", pbuff);
-    memcpy(pbuff, buffer + 739, 37);
-    pbuff[37] = 0;
-    printm(M_BARE, "  739 -  37- AbsFile: %s\n", pbuff);
-    memcpy(pbuff, buffer + 776, 37);
-    pbuff[37] = 0;
-    printm(M_BARE, "  776 -  37- BibFile: %s\n", pbuff);
-    printm(M_BARE, "  813 -  17- DTCreat: " + format_date(&buffer[813]) + "\n");
-    printm(M_BARE, "  830 -  17- DTModif: " + format_date(&buffer[830]) + "\n");
-    printm(M_BARE, "  847 -  17- DTExpir: " + format_date(&buffer[847]) + "\n");
-    printm(M_BARE, "  864 -  17- DTEffec: " + format_date(&buffer[864]) + "\n");
-    
-    printm(M_BARE, "Root record:\n");
-    show_head_entry();
-    show_entry((DirEntry *) &(buffer[156]));
-    
-    return 1;
-}
-
-int cdutils::get_iso_infos() {
-    Byte buffer[2048];
-    char pbuff[130];
-    short int s, nogood = 0;
-    int rootsec;
-
-    read_sector(buffer, GUESS, 16);
-
-    memcpy(pbuff, buffer + 1, 5);
-    pbuff[5] = 0;
-
-    s = *((short int *) &(buffer[6]));
-    if (buffer[0] != 1) nogood = 1;
-    if (strcmp(pbuff, "CD001")) nogood = 1;
-    if (s != 1) nogood = 1;
-    
-    if (nogood) {
-	printm(M_ERROR, "Not a valid iso9660 file.\n");
-	return 0;
-    }
-    
-    pt1 = *((short int *) &(buffer[140]));
-    pt2 = *((short int *) &(buffer[144]));
-    snum = *((int *) &(buffer[80]));
-    ptl = *((long int *) &(buffer[132]));
-    rootsec = ((struct DirEntry *) (&buffer[156]))->Sector;
-    read_sector(buffer, GUESS, rootsec);
-    rootDir = (struct DirEntry *) malloc(buffer[0]);
-    memcpy(rootDir, buffer, buffer[0]);
-    return 1;
-}
-
-int cdutils::get_pt_infos() {
-    Byte * buffer;
-    
-    if ((pt1 <= 0) && (pt2 <= 0))
-	if (!get_iso_infos())
-	    return 0;
-	    
-    if ((!pt1) & (!pt2)) {
-	printm(M_ERROR, "No path table defined.\n");
-	return 0;
-    }
-    
-    buffer = (Byte *) malloc(ptl);
-    read_datas(buffer, ptl, GUESS, !pt1 ? pt2 : pt1);
-    
-    if (buffer[0] == 1)
-	if (buffer[1] == 0)
-	    if (buffer[6] == 1)
-		if (buffer[7] == 0)
-		    if (buffer[8] == 0)
-			if (buffer[9] == 0)
-			    root = *((unsigned long int *) &(buffer[2]));
-
-    free(buffer);
-    return root ? 1 : 0;
-}
-
-int cdutils::show_pt_infos() {
-    Byte * buffer;
-    char pbuf[100];
-    int i, ptr;
-    
-    if ((pt1 <= 0) && (pt2 <= 0))
-	if (!get_iso_infos())
-	    return 0;
-	    
-    if ((!pt1) & (!pt2)) {
-	printm(M_ERROR, "No path table defined.\n");
-	return 0;
-    }
-    
-    buffer = (Byte *) malloc(ptl + 2);
-    read_datas(buffer, ptl, GUESS, !pt1 ? pt2 : pt1);
-
-    printm(M_BARE, "node^paren@sector : name\n");
-    for (ptr = 0, i = 1; buffer[ptr]; ptr += ptr & 1, i++) {
-	strncpy(pbuf, (char *) &(buffer[8 + ptr]), buffer[ptr]);
-	pbuf[buffer[ptr]] = 0;
-	printm(M_BARE, "%3i ^ %3i @ %6i: %s\n", i, *((unsigned short *) &(buffer[6 + ptr])), *((unsigned long *) &(buffer[2 + ptr])), pbuf);
-	ptr += 8 + buffer[ptr];
-    }
-
-    free(buffer);
-    return 1;
-}
-
-struct cdutils::DirEntry cdutils::find_path(String path) {
-    char * newpath = path.strdup();
-    char ** pts = split(newpath, '/');
-    struct DirEntry dir = {0, 0, 0, 0, 0};
-    
-    if ((pt1 <= 0) && (pt2 <= 0))
-	if (!get_iso_infos()) {
-	    free(newpath);
-	    return dir;
-	}
-	    
-    if ((!pt1) & (!pt2)) {
-	printm(M_ERROR, "No path table defined.\n");
-	free(newpath);
-	return dir;
-    }
-    
-    if (!**pts)
-	pts++;
-
-    for (dir = *rootDir; *pts; pts++) {
-	if (!strlen(*pts))
-	    continue;
-	dir = find_dir_entry(&dir, *pts);
-	if (!dir.R) {
-	    free(newpath);
-	    return dir;
-	}
-    }
-    
-    free(newpath);
-    return dir;
-}
-
-struct cdutils::DirEntry cdutils::find_parent(String path) {
-    char * newpath = path.strdup();
-    char ** pts, * p;
-    struct DirEntry dir = {0, 0, 0, 0, 0};
-    
-    if ((p = strchr(newpath, '/'))) {
-	*p = 0;
-    }
-    if (!*newpath) {
-	free(newpath);
-	return *rootDir;
-    }
-    pts = split(newpath, '/');
-    
-    if ((pt1 <= 0) && (pt2 <= 0))
-	if (!get_iso_infos()) {
-	    free(newpath);
-	    return dir;
-	}
-	    
-    if ((!pt1) & (!pt2)) {
-	printm(M_ERROR, "No path table defined.\n");
-	free(newpath);
-	return dir;
-    }
-    
-    if (!**pts)
-	pts++;
-
-    for (dir = *rootDir; *pts; pts++) {
-	if (!strlen(*pts))
-	    continue;
-	dir = find_dir_entry(&dir, *pts);
-	if (!dir.R) {
-	    free(newpath);
-	    return dir;
-	}
-    }
-    
-    free(newpath);
-    return dir;
-}
-
-struct cdutils::DirEntry * cdutils::find_path(Byte ** bufout, String path) {
-    char * newpath = path.strdup();
-    char ** pts = split(newpath, '/');
-    struct DirEntry * dir;
-
-    *bufout = 0;
-    
-    if ((pt1 <= 0) && (pt2 <= 0))
-	if (!get_iso_infos()) {
-	    free(newpath);
-	    return 0;
-	}
-	    
-    if ((!pt1) & (!pt2)) {
-	printm(M_ERROR, "No path table defined.\n");
-	free(newpath);
-	return 0;
-    }
-    
-    if (!**pts)
-	pts++;
-
-    for (dir = rootDir; *pts; pts++) {
-	if (!strlen(*pts))
-	    continue;
-	dir = find_dir_entry(bufout, dir, *pts);
-	if (!dir) {
-	    free(newpath);
-            free(*bufout);
-	    return 0;
-	}
-    }
-    
-    if (!dir) {
-        free(*bufout);
-    }
-    
-    free(newpath);
-    return dir;
-}
-
-struct cdutils::DirEntry * cdutils::find_parent(Byte ** bufout, String path) {
-    char * newpath = path.strdup();
-    char ** pts, * p;
-    struct DirEntry * dir;
-
-    *bufout = 0;
-    
-    if ((p = strchr(newpath, '/'))) {
-	*p = 0;
-    }
-    if (!*newpath) {
-	free(newpath);
-	return rootDir;
-    }
-    pts = split(newpath, '/');
-    
-    if ((pt1 <= 0) && (pt2 <= 0))
-	if (!get_iso_infos()) {
-	    free(newpath);
-	    return 0;
-	}
-	    
-    if ((!pt1) & (!pt2)) {
-	printm(M_ERROR, "No path table defined.\n");
-	free(newpath);
-	return 0;
-    }
-    
-    if (!**pts)
-	pts++;
-
-    for (dir = rootDir; *pts; pts++) {
-        free(*bufout);
-	if (!strlen(*pts))
-	    continue;
-	dir = find_dir_entry(bufout, dir, *pts);
-	if (!dir) {
-	    free(newpath);
-	    return dir;
-	}
-    }
-
-    if (!dir) {
-        free(*bufout);
-    }
-    
-    free(newpath);
-    return dir;
-}
-
-cdfile::cdfile(cdutils * _cd, const cdutils::DirEntry * d, int _mode) : Handle(-1), cd(_cd), sector(d->Sector), mode(_mode), size(d->Size), name(d->id) {
-    if (mode == GUESS) {
-        mode = cd->guess_type(sector);
-    }
-    dir = (cdutils::DirEntry *) malloc(d->R);
-    memcpy(dir, d, d->R);
-    itell = 0;
-}
-
-cdfile::cdfile(cdutils * _cd, int _sector, ssize_t _size, int _mode) : Handle(-1), cd(_cd), sector(_sector), mode(_mode), size(_size), name("raw reading") {
-    Byte datas[2352];
-    bool eof;
-
-    if (mode == GUESS) {
-        mode = cd->guess_type(sector);
-    }
-    if (_size == -1) {
-        size = 0;
-        if ((mode == MODE2_FORM1) || (mode == MODE2_FORM2)) {
-            do {
-                cd->read_sector(datas, MODE_RAW, sector + size++);
-                eof = datas[18] & 0x80;
-            } while (!eof);
-            size *= sec_sizes[mode];
-        }
-    }
-    dir = 0;
-    itell = 0;
-}
-
-cdfile::~cdfile() {
-    free(dir);
-}
-
-ssize_t cdfile::read(void *buf, size_t count) throw (GeneralException) {
-    Byte buffer[2352];
-    size_t startsec, startbyte, nstartbytes;
-
-    count = MIN(count, (size_t) (size - itell));
-
-    if (!count) {
-        close();
-        return 0;
-    }
-
-    startsec = itell / sec_sizes[mode] + sector;
-    startbyte = itell % sec_sizes[mode];
-    nstartbytes = sec_sizes[mode] - startbyte;
-    nstartbytes = MIN(nstartbytes, count);
-    count -= nstartbytes;
-
-    cd->read_sector(buffer, mode, startsec);
-    memcpy(buf, buffer + startbyte, nstartbytes);
-    buf = (Byte *) buf + nstartbytes;
-
-    if (count) {
-        cd->read_datas((Byte *) buf, count, mode, startsec + 1);
-    }
-
-    itell += count + nstartbytes;
-
-    return count + nstartbytes;
-}
-
-bool cdfile::CanRead() const {
-    return true;
-}
-
-String cdfile::GetName() const {
-    return String("cdfile: ") + name;
-}
-
-bool cdfile::CanWatch() const {
-    return false;
-}
-
-ssize_t cdfile::GetSize() const {
-    return size;
-}
-
-bool cdfile::CanSeek() const {
-    return true;
-}
-
-off_t cdfile::seek(off_t off, int wheel) throw (GeneralException) {
-    switch (wheel) {
-    case SEEK_SET:
-        itell = off;
-        break;
-    case SEEK_CUR:
-        itell += off;
-        break;
-    case SEEK_END:
-        itell = size + off;
-        break;
-    }
-    return itell;
-}
+/*
+ *  PSX-Tools Bundle Pack
+ *  Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ * 
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* $Id: cdutils.cpp,v 1.31 2004-10-19 15:58:41 pixel Exp $ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "generic.h"
+#include "cdutils.h"
+#include "Output.h"
+
+const long sec_sizes[7] =  {0, 2048, 2336, 2048, 2324, 2352, 2352};
+const long sec_offsts[7] = {0,   16,   16,   24,   24,    0,    0};
+const String sec_modes[7] = {"MODE 0 (empty)", "MODE 1", "MODE 2", "MODE 2 FORM 1", "MODE 2 FORM 2", "Raw", "Autodetect"};
+
+cdutils::cdutils(Handle * r, Handle * w) : rootDir(0), f_iso_r(r), f_iso_w(w), ppf_file(0), pt1(-1), pt2(-1), snum(0), ptl(0), root(0) {}
+
+cdutils::~cdutils() {
+    if (ppf_file)
+	delete ppf_file;
+    free(rootDir);
+}
+
+unsigned char cdutils::from_BCD(unsigned char x) {
+    return ((x & 0xf) + ((x & 0xf0) >> 4) * 10);
+}
+
+unsigned char cdutils::to_BCD(unsigned char x) {
+    return ((x / 10) << 4) | (x % 10);
+}
+
+bool cdutils::is_valid_BCD(unsigned char x) {
+    return (((x & 15) < 10) && ((x >> 4) < 10));
+}
+
+unsigned long cdutils::from_MSF(unsigned char m, unsigned char s, unsigned char f, unsigned long start) {
+    return (from_BCD(m) * 60 + from_BCD(s)) * 75 + from_BCD(f) - start;
+}
+
+unsigned long cdutils::from_MSF(unsigned long msf, unsigned long start) {
+    unsigned char
+    f = msf & 0xff,
+    s = (msf >> 8) & 0xff,
+    m = (msf >> 16) & 0xff;
+    
+    return from_MSF(m, s, f, start);
+}
+
+void cdutils::to_MSF(int sect, unsigned char & m, unsigned char & s, unsigned char & f, unsigned long start) {
+    sect += start;
+    f = to_BCD(sect % 75);
+    sect /= 75;
+    s = to_BCD(sect % 60);
+    m = to_BCD(sect / 60);
+}
+
+unsigned long cdutils::to_MSF(int sect, unsigned long start) {
+    unsigned char m, s, f;
+    to_MSF(sect, m, s, f, start);
+    return f | (s << 8) | (m << 16);
+}
+
+Handle * cdutils::open_ppf(String ppf, String comment) throw (GeneralException) {
+    int i, l;
+
+    if (ppf_file)
+	throw GeneralException("Tried to open_ppf() while already opened.");
+    ppf_file = new Output(ppf);
+    ppf_file->write("PPF20\001", 6);
+    
+    l = comment.strlen();
+    if (l >= 50) {
+	ppf_file->write(comment.to_charp(), 50);
+    } else {
+	char * t = " ";
+	ppf_file->write(comment.to_charp(), l);
+	for (i = l; i < 50; i++) {
+	    ppf_file->write(t, 1);
+	}
+    }
+    
+    l = f_iso_r->GetSize();
+    ppf_file->write(&l, sizeof(l));
+    
+    f_iso_r->seek(0x9320, SEEK_SET);
+//    copy(f_iso_r, ppf_file, 1024);
+    return ppf_file;
+}
+
+void cdutils::write_ppf(Byte * old_sec, Byte * new_sec, int sec_num) {
+    int i, l = 0, o;
+    
+    for (i = 0; i < 2352; i++) {
+	if (old_sec[i] == new_sec[i]) {
+	    if (l != 0) {
+		o = 2352 * sec_num + i;
+		ppf_file->write(&o, sizeof(o));
+		ppf_file->write(&l, 1);
+		ppf_file->write(new_sec + i - l - 1, l);
+		l = 0;
+	    }
+	} else {
+	    l++;
+	    if (l == 255) {
+		o = 2352 * sec_num + i;
+		ppf_file->write(&o, 4);
+		ppf_file->write(&l, 1);
+		ppf_file->write(new_sec + i - 255, 255);
+		l = 0;
+	    }
+	}
+    }
+}
+
+void cdutils::close_ppf() throw (GeneralException) {
+    if (ppf_file) {
+	delete ppf_file;
+	ppf_file = 0;
+    } else {
+	throw GeneralException("Tried to close_ppf() without previous opening");
+    }
+}
+
+void cdutils::set_iso_w(Handle * w) {
+    if (!f_iso_w)
+	f_iso_w = w;
+}
+
+String cdutils::format_date(String input) {
+    String output;
+    
+    output  = input.extract(6, 7) + '/';
+    output += input.extract(4, 5) + '/';
+    output += input.extract(0, 3) + ' ';
+    output += input.extract(8, 9) + ':';
+    output += input.extract(10, 11) + ':';
+    output += input.extract(12, 13) + '.';
+    output += input.extract(14, 15);
+    output += String("").set("%+3.1f", ((float) (*((input.to_charp()) + 16))) / 4);
+    return output;
+}
+
+Uint16 cdutils::swap_word(Uint16 i) {
+    return (i >> 8) | (i << 8);
+}
+
+Uint32 cdutils::swap_dword(Uint32 i) {
+    return (i >> 24) | ((i >> 8) & 0x0000ff00) | ((i << 8) & 0x00ff0000) | (i << 24);
+}
+
+int cdutils::guess_type(int number) {
+    Byte header[24];
+    
+    if (number >= 0) {
+	sector_seek(number);
+    }
+    
+    f_iso_r->read(header, 24);
+    f_iso_r->seek(-24, SEEK_CUR);
+    if (header[15] == 1) {
+	return MODE_1;
+    } else if (header[15] == 2) {
+	if (*((unsigned long *) &(header[16])) == *((unsigned long *) &(header[20]))) {
+	    if ((header[16] == 0) && (header[17] == 0) && (header[19] == 0)) {
+		if (header[18] & 0x20) {
+		    return MODE_2_FORM_2;
+		} else {
+		    return MODE_2_FORM_1;
+		}
+	    }
+	}
+	return MODE_2;
+    }
+    
+    return MODE_0;
+}
+
+void cdutils::sector_seek(long sector) {
+    f_iso_r->seek(2352 * sector);
+    if (f_iso_w)
+        f_iso_w->seek(2352 * sector);
+}
+
+long cdutils::read_sector(Byte * buffer, int type, int number) {
+    if (number >= 0) {
+	sector_seek(number);
+    }
+    
+    if (type == GUESS) {
+	type = guess_type();
+    }
+    
+    f_iso_r->seek(sec_offsts[type], SEEK_CUR);
+    f_iso_r->read(buffer, sec_sizes[type]);
+    f_iso_r->seek(2352 - sec_offsts[type] - sec_sizes[type], SEEK_CUR);
+    return sec_sizes[type];
+}
+
+void cdutils::read_datas(Byte * buffer, long size, int type, int number) {
+    Byte sector[2352];
+    int i, n, reste;
+    
+    if (type == GUESS) {
+	type = guess_type(number);
+    }
+    
+    n = size / sec_sizes[type];
+    reste = size - n * sec_sizes[type];
+    
+    sector_seek(number);
+    for (i = 0; i < n; i++) {
+	read_sector(buffer + i * sec_sizes[type], type);
+    }
+    
+    if (reste) {
+	read_sector(sector, type);
+	bcopy((char *) sector, (char *) (buffer + n * sec_sizes[type]), reste);
+    }
+}
+
+void cdutils::read_file(Handle * file, long size, int type, int number) {
+    Byte sector[2352];
+    int i, n, reste;
+    
+    if (type == GUESS) {
+	type = guess_type(number);
+    }
+    
+    n = size / sec_sizes[type];
+    reste = size - n * sec_sizes[type];
+    
+    for (i = 0; i < n; i++) {
+	sector_seek(number + i);
+	try {
+	    read_sector(sector, type);
+	}
+	catch(...) {
+	    memset(sector, 0, 2352);
+	}
+	file->write(sector, sec_sizes[type]);
+    }
+    
+    sector_seek(number + n);
+    if (reste) {
+	try {
+	    read_sector(sector, type);
+	}
+	catch(...) {
+	    memset(sector, 0, 2352);
+	}
+	file->write(sector, reste);
+    }
+}
+
+void cdutils::write_sector(Byte * buffer, int type, int number) throw (GeneralException) {
+    Byte old_sector[2352], new_sector[2352];
+
+    if (type == GUESS) {
+	type = guess_type(number);
+    }
+
+    if (number >= 0) {
+	sector_seek(number);
+    } else {
+	number = f_iso_r->tell() / 2352;
+    }
+    
+    f_iso_r->read(old_sector, 2352);
+    
+    yazedc_o.minute = old_sector[12];
+    yazedc_o.second = old_sector[13];
+    yazedc_o.frame = old_sector[14];
+    
+    bcopy((char *) old_sector, (char *) new_sector, 2532);
+    bcopy((char *) buffer, (char *) new_sector + sec_offsts[type], sec_sizes[type]);
+    
+    yazedc_o.do_encode_L2(new_sector, type, 0);
+    if (f_iso_w) {
+	f_iso_w->write(new_sector, 2352);
+    } else if (ppf_file) {
+	write_ppf(old_sector, new_sector, number);
+    } else {
+	throw GeneralException("No writing method for iso file");
+    }
+}
+
+void cdutils::write_datas(Byte * buffer, long size, int type, int number) {
+    long nbsectors, i;
+    unsigned char sector[2352];
+
+    if (type == GUESS) {
+	type = guess_type(number);
+    }
+
+    if (number >= 0) {
+	sector_seek(number);
+    }
+    
+    nbsectors = size / sec_sizes[type];
+    
+    for (i = 0; i < nbsectors; i++) {
+	write_sector(buffer + i * sec_sizes[type], type, number + i);
+    }
+
+    if (size % sec_sizes[type]) {
+	memset(sector, 0, 2352);
+	bcopy((char *) (buffer + i * sec_sizes[type]), (char *) sector, size % sec_sizes[type]);
+	write_sector(sector, type, number + i);
+    }
+}
+
+void cdutils::write_file(Handle * file, long size, int type, int number) {
+    long nbsectors, i;
+    unsigned char buffer[2352];
+    
+    if (type == GUESS) {
+	type = guess_type(number);
+    }
+    
+    if (number >= 0) {
+	sector_seek(number);
+    }
+    
+    if (size < 0)
+        size = file->GetSize();
+    nbsectors = size / sec_sizes[type];
+    
+    if (size % sec_sizes[type]) {
+	nbsectors++;
+    }
+    
+    for (i = 0; i < nbsectors; i++) {
+	memset(buffer, 0, 2352);
+	size = file->read(buffer, sec_sizes[type]);
+	write_sector(buffer, type);
+    }
+}
+
+void cdutils::create_sector(int type, int number, bool eof) throw (GeneralException) {
+    Byte sector[2352];
+    if (!f_iso_w)
+	throw GeneralException("Can't create sector: ISO not in write mode");
+    
+    to_MSF(number, yazedc_o.minute, yazedc_o.second, yazedc_o.frame);
+    memset(sector, 0, 2352);
+    if ((type == MODE2_FORM1) || (type == MODE2_FORM2)) {
+	sector[16] = sector[20] = 0;  // File Number
+	sector[17] = sector[21] = 0;  // Channel Number
+	sector[18] = sector[22] = 8 | (eof ? 129 : 0) |
+	                          (type == MODE2_FORM2 ? 32 : 0);
+	sector[19] = sector[23] = 0;  // Coding Info
+    }
+    yazedc_o.do_encode_L2(sector, type, 0);
+
+    f_iso_w->seek(2352 * number);
+    
+    f_iso_w->write(sector, 2352);
+    
+    sector_seek(number);
+}
+
+void cdutils::show_head_entry(void) {
+    printm(M_BARE, "Sector   Size        Date       Time       Flags  Name           XA flags\n");
+}
+
+int cdutils::show_entry(struct DirEntry * dir) {
+    char pbuf[200], pad;
+    int s;
+    if ((!dir) || (!dir->R)) {
+	return 1;
+    }
+    
+    strncpy(pbuf, dir->id, dir->N);
+    pbuf[dir->N] = 0;
+    if ((dir->N == 1) && (pbuf[0] == 0)) {
+	strcpy(pbuf, ".");
+    }
+    if ((dir->N == 1) && (pbuf[0] == 1)) {
+	strcpy(pbuf, "..");
+    }
+
+    s = 33 + dir->N;
+    if (s & 1) {
+        s++;
+        pad = 1;
+    } else {
+        pad = 0;
+    }
+    if (s != dir->R) {
+        if ((s + 14) == dir->R) {
+            Byte * p;
+            p = (Byte *) dir->id + dir->N + pad;
+            if ((p[6] == 'X') && (p[7] == 'A')) {
+                sprintf(pbuf, "%-14s %c%c%c%c%c", pbuf,
+                    p[4] & 0x80 ? 'd' : '-',
+                    p[4] & 0x40 ? 'a' : '-',
+                    p[4] & 0x20 ? 's' : '-',
+                    p[4] & 0x10 ? 'x' : '-',
+                    p[4] & 0x08 ? 'f' : '-');
+            }
+        }
+    }
+
+    if (dir->Year < 70)
+	dir->Year += 100;
+
+    printm(M_BARE, "%6i %9i %2i/%02i/%04i %2i:%02i:%02i%+03.1f %c%c%c%c%c%c%c%c %s\n",
+           dir->Sector, dir->Size, dir->Day, dir->Month, dir->Year + 1900, dir->Hour, dir->Minute, dir->Second, ((float) dir->Offset) / 4,
+           dir->Flags &  1 ? 'H' : '-', dir->Flags &  2 ? 'D' : '-', dir->Flags &  4 ? 'A' : '-', dir->Flags &   8 ? 'R' : '-',
+	   dir->Flags & 16 ? 'P' : '-', dir->Flags & 32 ? '1' : '-', dir->Flags & 64 ? '1' : '-', dir->Flags & 128 ? 'C' : '-', pbuf);
+    return dir->R;
+}
+
+int cdutils::show_dir(struct DirEntry * dir) {
+    unsigned int ptr;
+    Byte * buffer;
+    
+    if (!(dir->Flags & 2)) {
+	return 0;
+    }
+    
+    buffer = (Byte *) malloc(dir->Size);
+    read_datas(buffer, dir->Size, GUESS, dir->Sector);
+    
+    ptr = 0;
+    while(ptr < dir->Size) {
+	ptr += show_entry((struct DirEntry *) &(buffer[ptr]));
+    }
+    
+    free(buffer);
+    return 1;
+}
+
+struct cdutils::DirEntry cdutils::find_dir_entry(struct DirEntry * dir, String name) {
+    unsigned int ptr, size;
+    unsigned char * buffer;
+    struct DirEntry r = {0, 0, 0, 0, 0};
+    
+    if (!(dir->Flags & 2)) {
+	return r;
+    }
+    
+    buffer = (unsigned char *) malloc(size = dir->Size);
+    read_datas(buffer, dir->Size, GUESS, dir->Sector);
+    
+    ptr = 0;
+    while(ptr < size) {
+	dir = (struct DirEntry *) &(buffer[ptr]);
+	if (!dir->R) {
+	    ptr++;
+	} else {
+	    if (!strncmp(name.to_charp(), (char *) &(dir->id), dir->N)) {
+		r = *dir;
+	    }
+	    ptr += dir->R;
+	}
+    }
+
+    free(buffer);
+    return r;
+}
+
+struct cdutils::DirEntry * cdutils::find_dir_entry(Byte ** bufout, struct cdutils::DirEntry * dir, String name) {
+    unsigned int ptr, size;
+    Byte * buffer;
+    struct DirEntry * rdir = 0;
+    *bufout = 0;
+    
+    if (!(dir->Flags & 2)) {
+	return 0;
+    }
+    
+    buffer = (Byte *) malloc(size = dir->Size);
+    read_datas(buffer, dir->Size, GUESS, dir->Sector);
+    
+    ptr = 0;
+    while(ptr < size) {
+	dir = (struct DirEntry *) &(buffer[ptr]);
+	if (!dir->R) {
+	    ptr++;
+	} else {
+	    if (!strncmp(name.to_charp(), (char *) &(dir->id), dir->N)) {
+		rdir = dir;
+	    }
+	    ptr += dir->R;
+	}
+    }
+
+    if (rdir && rdir->R) {
+        free(*bufout);
+	*bufout = buffer;
+    } else {
+	free(buffer);
+        rdir = 0;
+    }
+    return rdir;
+}
+
+int cdutils::show_iso_infos() {
+    char buffer[2048];
+    char pbuff[130];
+    short int s, nogood = 0;
+
+    read_sector((Byte *) buffer, GUESS, 16);
+
+    printm(M_BARE, "Sector guessed mode : " + sec_modes[guess_type(16)] + "\n");
+    printm(M_BARE, "offset-size-info    : contents\n");
+    printm(M_BARE, "    0 -   1-  1     : %i\n", buffer[0]);
+    memcpy(pbuff, buffer + 1, 5);
+    pbuff[5] = 0;
+    printm(M_BARE, "    1 -   5-`CD001' : %s\n", pbuff);
+    printm(M_BARE, "    6 -   2-  1     : %i\n", s = *((short int *) &(buffer[6])));
+    printm(M_BARE, "(*this was the signature*)\n");
+    if (buffer[0] != 1) nogood = 1;
+    if (strcmp(pbuff, "CD001")) nogood = 1;
+    if (s != 1) nogood = 1;
+    
+    if (nogood) {
+	printm(M_BARE, "Not a valid iso9660 file.\n");
+	return 0;
+    }
+    
+    memcpy(pbuff, buffer + 8, 32);
+    pbuff[32] = 0;
+    printm(M_BARE, "    8 -  32- SYSID  : %s\n", pbuff);
+    memcpy(pbuff, buffer + 40, 32);
+    pbuff[32] = 0;
+    printm(M_BARE, "   40 -  32- VOLID  : %s\n", pbuff);
+    printm(M_BARE, "   80 -   8- SNum   : %li\n", *((long int *) &(buffer[80])));
+    printm(M_BARE, "  120 -   4- VOLSiz : %i\n", *((short int *) &(buffer[120])));
+    printm(M_BARE, "  124 -   4- VOLNum : %i\n", *((short int *) &(buffer[124])));
+    printm(M_BARE, "  128 -   4- SSize  : %i\n", *((short int *) &(buffer[128])));
+    printm(M_BARE, "  132 -   8- PSize  : %li\n", *((long int *) &(buffer[132])));
+    printm(M_BARE, "  140 -   4- 1SLPath: %i\n", *((long int *) &(buffer[140])));
+    printm(M_BARE, "  144 -   4- 2SLPath: %i\n", *((long int *) &(buffer[144])));
+    printm(M_BARE, "  148 -   4- 1SBPath: %i\n", swap_word(*((long int *) &(buffer[150]))));
+    printm(M_BARE, "  152 -   4- 2SBPath: %i\n", swap_word(*((long int *) &(buffer[154]))));
+    memcpy(pbuff, buffer + 190, 128);
+    pbuff[128] = 0;
+    printm(M_BARE, "  190 - 128- VStId  : %s\n", pbuff);
+    memcpy(pbuff, buffer + 318, 128);
+    pbuff[128] = 0;
+    printm(M_BARE, "  318 - 128- PubId  : %s\n", pbuff);
+    memcpy(pbuff, buffer + 446, 128);
+    pbuff[128] = 0;
+    printm(M_BARE, "  446 - 128- DPrId  : %s\n", pbuff);
+    memcpy(pbuff, buffer + 574, 128);
+    pbuff[128] = 0;
+    printm(M_BARE, "  574 - 128- AppId  : %s\n", pbuff);
+    memcpy(pbuff, buffer + 702, 37);
+    pbuff[37] = 0;
+    printm(M_BARE, "  702 -  37- CpyFile: %s\n", pbuff);
+    memcpy(pbuff, buffer + 739, 37);
+    pbuff[37] = 0;
+    printm(M_BARE, "  739 -  37- AbsFile: %s\n", pbuff);
+    memcpy(pbuff, buffer + 776, 37);
+    pbuff[37] = 0;
+    printm(M_BARE, "  776 -  37- BibFile: %s\n", pbuff);
+    printm(M_BARE, "  813 -  17- DTCreat: " + format_date(&buffer[813]) + "\n");
+    printm(M_BARE, "  830 -  17- DTModif: " + format_date(&buffer[830]) + "\n");
+    printm(M_BARE, "  847 -  17- DTExpir: " + format_date(&buffer[847]) + "\n");
+    printm(M_BARE, "  864 -  17- DTEffec: " + format_date(&buffer[864]) + "\n");
+    
+    printm(M_BARE, "Root record:\n");
+    show_head_entry();
+    show_entry((DirEntry *) &(buffer[156]));
+    
+    return 1;
+}
+
+int cdutils::get_iso_infos() {
+    Byte buffer[2048];
+    char pbuff[130];
+    short int s, nogood = 0;
+    int rootsec;
+
+    read_sector(buffer, GUESS, 16);
+
+    memcpy(pbuff, buffer + 1, 5);
+    pbuff[5] = 0;
+
+    s = *((short int *) &(buffer[6]));
+    if (buffer[0] != 1) nogood = 1;
+    if (strcmp(pbuff, "CD001")) nogood = 1;
+    if (s != 1) nogood = 1;
+    
+    if (nogood) {
+	printm(M_ERROR, "Not a valid iso9660 file.\n");
+	return 0;
+    }
+    
+    pt1 = *((short int *) &(buffer[140]));
+    pt2 = *((short int *) &(buffer[144]));
+    snum = *((int *) &(buffer[80]));
+    ptl = *((long int *) &(buffer[132]));
+    rootsec = ((struct DirEntry *) (&buffer[156]))->Sector;
+    read_sector(buffer, GUESS, rootsec);
+    rootDir = (struct DirEntry *) malloc(buffer[0]);
+    memcpy(rootDir, buffer, buffer[0]);
+    return 1;
+}
+
+int cdutils::get_pt_infos() {
+    Byte * buffer;
+    
+    if ((pt1 <= 0) && (pt2 <= 0))
+	if (!get_iso_infos())
+	    return 0;
+	    
+    if ((!pt1) & (!pt2)) {
+	printm(M_ERROR, "No path table defined.\n");
+	return 0;
+    }
+    
+    buffer = (Byte *) malloc(ptl);
+    read_datas(buffer, ptl, GUESS, !pt1 ? pt2 : pt1);
+    
+    if (buffer[0] == 1)
+	if (buffer[1] == 0)
+	    if (buffer[6] == 1)
+		if (buffer[7] == 0)
+		    if (buffer[8] == 0)
+			if (buffer[9] == 0)
+			    root = *((unsigned long int *) &(buffer[2]));
+
+    free(buffer);
+    return root ? 1 : 0;
+}
+
+int cdutils::show_pt_infos() {
+    Byte * buffer;
+    char pbuf[100];
+    int i, ptr;
+    
+    if ((pt1 <= 0) && (pt2 <= 0))
+	if (!get_iso_infos())
+	    return 0;
+	    
+    if ((!pt1) & (!pt2)) {
+	printm(M_ERROR, "No path table defined.\n");
+	return 0;
+    }
+    
+    buffer = (Byte *) malloc(ptl + 2);
+    read_datas(buffer, ptl, GUESS, !pt1 ? pt2 : pt1);
+
+    printm(M_BARE, "node^paren@sector : name\n");
+    for (ptr = 0, i = 1; buffer[ptr]; ptr += ptr & 1, i++) {
+	strncpy(pbuf, (char *) &(buffer[8 + ptr]), buffer[ptr]);
+	pbuf[buffer[ptr]] = 0;
+	printm(M_BARE, "%3i ^ %3i @ %6i: %s\n", i, *((unsigned short *) &(buffer[6 + ptr])), *((unsigned long *) &(buffer[2 + ptr])), pbuf);
+	ptr += 8 + buffer[ptr];
+    }
+
+    free(buffer);
+    return 1;
+}
+
+struct cdutils::DirEntry cdutils::find_path(String path) {
+    char * newpath = path.strdup();
+    char ** pts = split(newpath, '/');
+    struct DirEntry dir = {0, 0, 0, 0, 0};
+    
+    if ((pt1 <= 0) && (pt2 <= 0))
+	if (!get_iso_infos()) {
+	    free(newpath);
+	    return dir;
+	}
+	    
+    if ((!pt1) & (!pt2)) {
+	printm(M_ERROR, "No path table defined.\n");
+	free(newpath);
+	return dir;
+    }
+    
+    if (!**pts)
+	pts++;
+
+    for (dir = *rootDir; *pts; pts++) {
+	if (!strlen(*pts))
+	    continue;
+	dir = find_dir_entry(&dir, *pts);
+	if (!dir.R) {
+	    free(newpath);
+	    return dir;
+	}
+    }
+    
+    free(newpath);
+    return dir;
+}
+
+struct cdutils::DirEntry cdutils::find_parent(String path) {
+    char * newpath = path.strdup();
+    char ** pts, * p;
+    struct DirEntry dir = {0, 0, 0, 0, 0};
+    
+    if ((p = strchr(newpath, '/'))) {
+	*p = 0;
+    }
+    if (!*newpath) {
+	free(newpath);
+	return *rootDir;
+    }
+    pts = split(newpath, '/');
+    
+    if ((pt1 <= 0) && (pt2 <= 0))
+	if (!get_iso_infos()) {
+	    free(newpath);
+	    return dir;
+	}
+	    
+    if ((!pt1) & (!pt2)) {
+	printm(M_ERROR, "No path table defined.\n");
+	free(newpath);
+	return dir;
+    }
+    
+    if (!**pts)
+	pts++;
+
+    for (dir = *rootDir; *pts; pts++) {
+	if (!strlen(*pts))
+	    continue;
+	dir = find_dir_entry(&dir, *pts);
+	if (!dir.R) {
+	    free(newpath);
+	    return dir;
+	}
+    }
+    
+    free(newpath);
+    return dir;
+}
+
+struct cdutils::DirEntry * cdutils::find_path(Byte ** bufout, String path) {
+    char * newpath = path.strdup();
+    char ** pts = split(newpath, '/');
+    struct DirEntry * dir;
+
+    *bufout = 0;
+    
+    if ((pt1 <= 0) && (pt2 <= 0))
+	if (!get_iso_infos()) {
+	    free(newpath);
+	    return 0;
+	}
+	    
+    if ((!pt1) & (!pt2)) {
+	printm(M_ERROR, "No path table defined.\n");
+	free(newpath);
+	return 0;
+    }
+    
+    if (!**pts)
+	pts++;
+
+    for (dir = rootDir; *pts; pts++) {
+	if (!strlen(*pts))
+	    continue;
+	dir = find_dir_entry(bufout, dir, *pts);
+	if (!dir) {
+	    free(newpath);
+            free(*bufout);
+	    return 0;
+	}
+    }
+    
+    if (!dir) {
+        free(*bufout);
+    }
+    
+    free(newpath);
+    return dir;
+}
+
+struct cdutils::DirEntry * cdutils::find_parent(Byte ** bufout, String path) {
+    char * newpath = path.strdup();
+    char ** pts, * p;
+    struct DirEntry * dir;
+
+    *bufout = 0;
+    
+    if ((p = strchr(newpath, '/'))) {
+	*p = 0;
+    }
+    if (!*newpath) {
+	free(newpath);
+	return rootDir;
+    }
+    pts = split(newpath, '/');
+    
+    if ((pt1 <= 0) && (pt2 <= 0))
+	if (!get_iso_infos()) {
+	    free(newpath);
+	    return 0;
+	}
+	    
+    if ((!pt1) & (!pt2)) {
+	printm(M_ERROR, "No path table defined.\n");
+	free(newpath);
+	return 0;
+    }
+    
+    if (!**pts)
+	pts++;
+
+    for (dir = rootDir; *pts; pts++) {
+        free(*bufout);
+	if (!strlen(*pts))
+	    continue;
+	dir = find_dir_entry(bufout, dir, *pts);
+	if (!dir) {
+	    free(newpath);
+	    return dir;
+	}
+    }
+
+    if (!dir) {
+        free(*bufout);
+    }
+    
+    free(newpath);
+    return dir;
+}
+
+cdfile::cdfile(cdutils * _cd, const cdutils::DirEntry * d, int _mode) : Handle(-1), cd(_cd), sector(d->Sector), mode(_mode), size(d->Size), name(d->id) {
+    if (mode == GUESS) {
+        mode = cd->guess_type(sector);
+    }
+    dir = (cdutils::DirEntry *) malloc(d->R);
+    memcpy(dir, d, d->R);
+    itell = 0;
+}
+
+cdfile::cdfile(cdutils * _cd, int _sector, ssize_t _size, int _mode) : Handle(-1), cd(_cd), sector(_sector), mode(_mode), size(_size), name("raw reading") {
+    Byte datas[2352];
+    bool eof;
+
+    if (mode == GUESS) {
+        mode = cd->guess_type(sector);
+    }
+    if (_size == -1) {
+        size = 0;
+        if ((mode == MODE2_FORM1) || (mode == MODE2_FORM2)) {
+            do {
+                cd->read_sector(datas, MODE_RAW, sector + size++);
+                eof = datas[18] & 0x80;
+            } while (!eof);
+            size *= sec_sizes[mode];
+        }
+    }
+    dir = 0;
+    itell = 0;
+}
+
+cdfile::~cdfile() {
+    free(dir);
+}
+
+ssize_t cdfile::read(void *buf, size_t count) throw (GeneralException) {
+    Byte buffer[2352];
+    size_t startsec, startbyte, nstartbytes;
+
+    count = MIN(count, (size_t) (size - itell));
+
+    if (!count) {
+        close();
+        return 0;
+    }
+
+    startsec = itell / sec_sizes[mode] + sector;
+    startbyte = itell % sec_sizes[mode];
+    nstartbytes = sec_sizes[mode] - startbyte;
+    nstartbytes = MIN(nstartbytes, count);
+    count -= nstartbytes;
+
+    cd->read_sector(buffer, mode, startsec);
+    memcpy(buf, buffer + startbyte, nstartbytes);
+    buf = (Byte *) buf + nstartbytes;
+
+    if (count) {
+        cd->read_datas((Byte *) buf, count, mode, startsec + 1);
+    }
+
+    itell += count + nstartbytes;
+
+    return count + nstartbytes;
+}
+
+bool cdfile::CanRead() const {
+    return true;
+}
+
+String cdfile::GetName() const {
+    return String("cdfile: ") + name;
+}
+
+bool cdfile::CanWatch() const {
+    return false;
+}
+
+ssize_t cdfile::GetSize() const {
+    return size;
+}
+
+bool cdfile::CanSeek() const {
+    return true;
+}
+
+off_t cdfile::seek(off_t off, int wheel) throw (GeneralException) {
+    switch (wheel) {
+    case SEEK_SET:
+        itell = off;
+        break;
+    case SEEK_CUR:
+        itell += off;
+        break;
+    case SEEK_END:
+        itell = size + off;
+        break;
+    }
+    return itell;
+}
diff --git a/lib/isobuilder.cpp b/lib/isobuilder.cpp
index 1414e96..2b60131 100644
--- a/lib/isobuilder.cpp
+++ b/lib/isobuilder.cpp
@@ -17,7 +17,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* $Id: isobuilder.cpp,v 1.13 2004-10-19 01:27:29 pixel Exp $ */
+/* $Id: isobuilder.cpp,v 1.14 2004-10-19 15:58:41 pixel Exp $ */
 
 #include "isobuilder.h"
 
@@ -289,7 +289,11 @@ int isobuilder::DirTree::buildentry(Byte * buffer, int spaceleft, bool put_xa) {
     d->BESector = cdutils::swap_dword(sector);
     d->Size = size;
     d->BESize = cdutils::swap_dword(size);
-    d->Year = creation.year - 1900;
+    if (creation.year >= 1000) {
+	d->Year = creation.year - 1900;
+    } else {
+	d->Year = creation.year;
+    }
     d->Month = creation.month;
     d->Day = creation.day;
     d->Hour = creation.hour;
@@ -840,7 +844,7 @@ void isobuilder::close(Handle * cue, int mode, int nsects) throw (GeneralExcepti
     sprintf(cdatas + 446, "%-128s", pvd.prepid.to_charp());
     sprintf(cdatas + 574, "%-128s", pvd.appid.to_charp());
     sprintf(cdatas + 702, "%-37s", pvd.copyright.to_charp());
-    sprintf(cdatas + 739, "%-37s", pvd.appid.to_charp());
+    sprintf(cdatas + 739, "%-37s", pvd.abstract.to_charp());
     sprintf(cdatas + 776, "%-37s", pvd.biblio.to_charp());
 
     pvd.volcreat.dump(datas + 813);
diff --git a/lib/luacd.cpp b/lib/luacd.cpp
index 97efe82..e4e2b23 100644
--- a/lib/luacd.cpp
+++ b/lib/luacd.cpp
@@ -1,1660 +1,1661 @@
-/*
- *  PSX-Tools Bundle Pack
- *  Copyright (C) 2002-2003 Nicolas "Pixel" Noble
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/* $Id: luacd.cpp,v 1.13 2004-05-03 12:55:04 pixel Exp $ */
-
-#include "luacd.h"
-
-
- /**************************\
-|**  class cdutils exports **|
- \**************************/
-
-Luacdutils::Luacdutils(cdutils * _cd) : cd(_cd) { }
-class Luacdfile : public LuaHandle {
+/*
+ *  PSX-Tools Bundle Pack
+ *  Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* $Id: luacd.cpp,v 1.14 2004-10-19 15:58:42 pixel Exp $ */
+
+#include "luacd.h"
+
+
+ /**************************\
+|**  class cdutils exports **|
+ \**************************/
+
+Luacdutils::Luacdutils(cdutils * _cd) : cd(_cd) { }
+class Luacdfile : public LuaHandle {

+  public:

+      Luacdfile(cdfile * h) : LuaHandle(h) {}

+};

+
+enum cdutils_methods_t {
+    CDUTILS_SETISOW = 0,
+    CDUTILS_GUESSTYPE,
+    CDUTILS_SECTORSEEK,
+    CDUTILS_READSECTOR,
+    CDUTILS_READDATAS,
+    CDUTILS_READFILE,
+    CDUTILS_WRITESECTOR,
+    CDUTILS_WRITEDATAS,
+    CDUTILS_WRITEFILE,
+    CDUTILS_GETISOINFOS,
+    CDUTILS_GETPTINFOS,
+    CDUTILS_FINDPATH,
+    CDUTILS_FINDPARENT,
+    CDUTILS_FINDDIRENTRY,
+    CDUTILS_NEWCDFILE,
+    CDUTILS_UPDATESIZE,
+    CDUTILS_UPDATESECTOR,
+    CDUTILS_CREATESECTOR,
+};
+
+enum cdutils_functions_t {
+    CDUTILS_NEWCDUTILS = 0,
+    CDUTILS_SWAPWORD,
+    CDUTILS_SWAPDWORD,
+    CDUTILS_FROM_BCD,
+    CDUTILS_TO_BCD,
+    CDUTILS_IS_VALID_BCD,
+    CDUTILS_FROM_MSF,
+    CDUTILS_TO_MSF,
+};
+
+struct lua_functypes_t cdutils_methods[] = {
+    { CDUTILS_SETISOW,      "set_iso_w",    1, 1, {LUA_OBJECT} },
+    { CDUTILS_GUESSTYPE,    "guessmode",    0, 1, {LUA_NUMBER} },
+    { CDUTILS_SECTORSEEK,   "sectorseek",   1, 1, {LUA_NUMBER} },
+    { CDUTILS_READSECTOR,   "readsector",   0, 2, {LUA_NUMBER, LUA_NUMBER} },
+    { CDUTILS_READDATAS,    "readdatas",    1, 3, {LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+    { CDUTILS_READFILE,     "readfile",     2, 4, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+    { CDUTILS_WRITESECTOR,  "writesector",  1, 3, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER} },
+    { CDUTILS_WRITEDATAS,   "writedatas",   2, 4, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+    { CDUTILS_WRITEFILE,    "writefile",    1, 4, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+    { CDUTILS_GETISOINFOS,  "getisoinfos",  0, 0, 0 },
+    { CDUTILS_GETPTINFOS,   "getptinfos",   0, 0, 0 },
+    { CDUTILS_FINDPATH,     "findpath",     1, 1, {LUA_STRING} },
+    { CDUTILS_FINDPARENT,   "findparent",   1, 1, {LUA_STRING} },
+    { CDUTILS_FINDDIRENTRY, "finddirentry", 2, 2, {LUA_OBJECT, LUA_STRING} },
+    { CDUTILS_NEWCDFILE,    "cdfile",       1, 3, {LUA_ANY, LUA_NUMBER, LUA_NUMBER} },
+    { CDUTILS_UPDATESIZE,   "updatesize",   2, 2, {LUA_STRING, LUA_NUMBER} },
+    { CDUTILS_UPDATESECTOR, "updatesector", 2, 2, {LUA_STRING, LUA_NUMBER} },
+    { CDUTILS_CREATESECTOR, "createsector", 2, 3, {LUA_NUMBER, LUA_NUMBER, LUA_BOOLEAN} },
+    { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t cdutils_functions[] = {
+    { CDUTILS_NEWCDUTILS,   "cdutils" ,     1, 2, {LUA_OBJECT, LUA_OBJECT} },
+    { CDUTILS_SWAPWORD,     "swapword",     1, 1, {LUA_NUMBER} },
+    { CDUTILS_SWAPDWORD,    "swapdword",    1, 1, {LUA_NUMBER} },
+    { CDUTILS_FROM_BCD,     "from_BCD",     1, 1, {LUA_NUMBER} },
+    { CDUTILS_TO_BCD,       "to_BCD",       1, 1, {LUA_NUMBER} },
+    { CDUTILS_IS_VALID_BCD, "is_valid_BCD", 1, 1, {LUA_NUMBER} },
+    { CDUTILS_FROM_MSF,     "from_MSF",     1, 4, {LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+    { CDUTILS_TO_MSF,       "to_MSF",       1, 2, {LUA_NUMBER, LUA_NUMBER} },
+    { -1, 0, 0, 0, 0 }
+};
+
+class sLua_cdutils : public Base {
+  public:
+    DECLARE_METHOD(cdutils, CDUTILS_SETISOW);
+    DECLARE_METHOD(cdutils, CDUTILS_GUESSTYPE);
+    DECLARE_METHOD(cdutils, CDUTILS_SECTORSEEK);
+    DECLARE_METHOD(cdutils, CDUTILS_READSECTOR);
+    DECLARE_METHOD(cdutils, CDUTILS_READDATAS);
+    DECLARE_METHOD(cdutils, CDUTILS_READFILE);
+    DECLARE_METHOD(cdutils, CDUTILS_WRITESECTOR);
+    DECLARE_METHOD(cdutils, CDUTILS_WRITEDATAS);
+    DECLARE_METHOD(cdutils, CDUTILS_WRITEFILE);
+    DECLARE_METHOD(cdutils, CDUTILS_GETISOINFOS);
+    DECLARE_METHOD(cdutils, CDUTILS_GETPTINFOS);
+    DECLARE_METHOD(cdutils, CDUTILS_FINDPATH);
+    DECLARE_METHOD(cdutils, CDUTILS_FINDPARENT);
+    DECLARE_METHOD(cdutils, CDUTILS_FINDDIRENTRY);
+    DECLARE_METHOD(cdutils, CDUTILS_NEWCDFILE);
+    DECLARE_METHOD(cdutils, CDUTILS_UPDATESIZE);
+    DECLARE_METHOD(cdutils, CDUTILS_UPDATESECTOR);
+    DECLARE_METHOD(cdutils, CDUTILS_CREATESECTOR);
+
+    DECLARE_FUNCTION(cdutils, CDUTILS_NEWCDUTILS);
+    DECLARE_FUNCTION(cdutils, CDUTILS_SWAPWORD);
+    DECLARE_FUNCTION(cdutils, CDUTILS_SWAPDWORD);
+    DECLARE_FUNCTION(cdutils, CDUTILS_FROM_BCD);
+    DECLARE_FUNCTION(cdutils, CDUTILS_TO_BCD);
+    DECLARE_FUNCTION(cdutils, CDUTILS_IS_VALID_BCD);
+    DECLARE_FUNCTION(cdutils, CDUTILS_FROM_MSF);
+    DECLARE_FUNCTION(cdutils, CDUTILS_TO_MSF);
+
+  private:
+    static int cdutils_proceed(Lua * L, int n, cdutils * obj, int caller);
+    static int cdutils_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luacdutils::pushmembers(Lua * L) {
+    pushme(L, cd);
+
+    PUSH_METHOD(cdutils, CDUTILS_SETISOW);
+    PUSH_METHOD(cdutils, CDUTILS_GUESSTYPE);
+    PUSH_METHOD(cdutils, CDUTILS_SECTORSEEK);
+    PUSH_METHOD(cdutils, CDUTILS_READSECTOR);
+    PUSH_METHOD(cdutils, CDUTILS_READDATAS);
+    PUSH_METHOD(cdutils, CDUTILS_READFILE);
+    PUSH_METHOD(cdutils, CDUTILS_WRITESECTOR);
+    PUSH_METHOD(cdutils, CDUTILS_WRITEDATAS);
+    PUSH_METHOD(cdutils, CDUTILS_WRITEFILE);
+    PUSH_METHOD(cdutils, CDUTILS_GETISOINFOS);
+    PUSH_METHOD(cdutils, CDUTILS_GETPTINFOS);
+    PUSH_METHOD(cdutils, CDUTILS_FINDPATH);
+    PUSH_METHOD(cdutils, CDUTILS_FINDPARENT);
+    PUSH_METHOD(cdutils, CDUTILS_FINDDIRENTRY);
+    PUSH_METHOD(cdutils, CDUTILS_NEWCDFILE);
+    PUSH_METHOD(cdutils, CDUTILS_UPDATESIZE);
+    PUSH_METHOD(cdutils, CDUTILS_UPDATESECTOR);
+    PUSH_METHOD(cdutils, CDUTILS_CREATESECTOR);
+}
+
+void Luacdutils::pushstatics(Lua * L) throw (GeneralException) {
+    CHECK_METHODS(cdutils);
+    CHECK_FUNCTIONS(cdutils);
+
+    PUSH_FUNCTION(cdutils, CDUTILS_NEWCDUTILS);
+    PUSH_FUNCTION(cdutils, CDUTILS_SWAPWORD);
+    PUSH_FUNCTION(cdutils, CDUTILS_SWAPDWORD);
+    PUSH_FUNCTION(cdutils, CDUTILS_FROM_BCD);
+    PUSH_FUNCTION(cdutils, CDUTILS_TO_BCD);
+    PUSH_FUNCTION(cdutils, CDUTILS_IS_VALID_BCD);
+    PUSH_FUNCTION(cdutils, CDUTILS_FROM_MSF);
+    PUSH_FUNCTION(cdutils, CDUTILS_TO_MSF);
+
+    L->push("MODE0");
+    L->push((lua_Number) MODE0);
+    L->setvar();
+
+    L->push("MODE1");
+    L->push((lua_Number) MODE1);
+    L->setvar();
+
+    L->push("MODE2");
+    L->push((lua_Number) MODE2);
+    L->setvar();
+
+    L->push("MODE2_FORM1");
+    L->push((lua_Number) MODE2_FORM1);
+    L->setvar();
+
+    L->push("MODE2_FORM2");
+    L->push((lua_Number) MODE2_FORM2);
+    L->setvar();
+
+    L->push("MORE_RAW");
+    L->push((lua_Number) MODE_RAW);
+    L->setvar();
+
+    L->push("GUESS");
+    L->push((lua_Number) GUESS);
+    L->setvar();
+
+    int i;
+
+    L->push("sec_sizes");
+    L->newtable();
+    for (i = 0; i <= GUESS; i++) {
+        L->push((lua_Number) i);
+        L->push((lua_Number) sec_sizes[i]);
+        L->settable();
+    }
+    L->setvar();
+
+    L->push("sec_offsts");
+    L->newtable();
+    for (i = 0; i <= GUESS; i++) {
+        L->push((lua_Number) i);
+        L->push((lua_Number) sec_offsts[i]);
+        L->settable();
+    }
+    L->setvar();
+
+    L->push("sec_modes");
+    L->newtable();
+    for (i = 0; i <= GUESS; i++) {
+        L->push((lua_Number) i);
+        L->push(sec_modes[i]);
+        L->settable();
+    }
+    L->setvar();
+}
+
+int sLua_cdutils::cdutils_proceed(Lua * L, int n, cdutils * cd, int caller) {
+    int r = 0, sect = -1, mode = GUESS, size = -1, i;
+    Handle * h;
+    Byte sdatas[2352], * datas;
+    String path;
+    cdutils::DirEntry * dir, * bdir, * adir, pdir;
+    bool invalid = false, eof = false;
+    int sector;
+    cdfile * cdf;
+
+    switch(caller) {
+    case CDUTILS_SETISOW:
+        h = (Handle *) LuaObject::getme(L, 2);
+        cd->set_iso_w(h);
+        break;
+    case CDUTILS_GUESSTYPE:
+        if (n == 1) {
+            sect = L->tonumber(2);
+        }
+        L->push((lua_Number) cd->guess_type(sect));
+        r = 1;
+        break;
+    case CDUTILS_SECTORSEEK:
+        sect = L->tonumber(2);
+        cd->sector_seek(sect);
+        break;
+    case CDUTILS_READSECTOR:
+        if (n >= 1)
+            sect = L->tonumber(2);
+        if (n == 2)
+            mode = L->tonumber(3);
+        size = cd->read_sector(sdatas, mode, sect);
+        L->newtable();
+        for (i = 0; i < size; i++) {
+            L->push((lua_Number) i);
+            L->push((lua_Number) sdatas[i]);
+            L->settable();
+        }
+        r = 1;
+        break;
+    case CDUTILS_READDATAS:
+        size = L->tonumber(2);
+        if (n >= 2)
+            sect = L->tonumber(3);
+        if (n == 3)
+            mode = L->tonumber(3);
+        datas = (Byte *) malloc(size);
+        cd->read_datas(datas, size, mode, sect);
+        L->newtable();
+        for (i = 0; i < size; i++) {
+            L->push((lua_Number) i);
+            L->push((lua_Number) datas[i]);
+            L->settable();
+        }
+        r = 1;
+        free(datas);
+        break;
+    case CDUTILS_READFILE:
+        h = (Handle *) LuaObject::getme(L, 2);
+        size = L->tonumber(5);
+        if (n >= 3)
+            sect = L->tonumber(4);
+        if (n == 4)
+            mode = L->tonumber(5);
+        cd->read_file(h, size, mode, sect);
+        break;
+    case CDUTILS_WRITESECTOR:
+        if (n >= 2)
+            sect = L->tonumber(3);
+        if (n == 3)
+            mode = L->tonumber(4);
+        for (i = 0; i < 2352; i++) {
+            L->push((lua_Number) i);
+            L->gettable(2);
+            sdatas[i] = L->tonumber();
+            L->pop();
+        }
+        cd->write_sector(datas, mode, sect);
+        break;
+    case CDUTILS_WRITEDATAS:
+        size = L->tonumber(3);
+        if (n >= 3)
+            sect = L->tonumber(4);
+        if (n == 4)
+            mode = L->tonumber(5);
+        datas = (Byte *) malloc(size);
+
+        for (i = 0; i < size; i++) {
+            L->push((lua_Number) i);
+            L->gettable(2);
+            sdatas[i] = L->tonumber();
+            L->pop();
+        }
+        cd->write_datas(datas, size, mode, sect);
+        free(datas);
+        break;
+    case CDUTILS_WRITEFILE:
+        h = (Handle *) LuaObject::getme(L, 2);
+        if (n >= 2)
+            size = L->tonumber(3);
+        if (n >= 3)
+            sect = L->tonumber(4);
+        if (n == 4)
+            mode = L->tonumber(5);
+        cd->write_file(h, size, mode, sect);
+        break;
+    case CDUTILS_GETISOINFOS:
+        L->push((lua_Number) cd->get_iso_infos());
+        r = 1;
+        break;
+    case CDUTILS_GETPTINFOS:
+        L->push((lua_Number) cd->get_pt_infos());
+        r = 1;
+        break;
+    case CDUTILS_FINDPATH:
+        path = L->tostring(2);
+        bdir = cd->find_path(&datas, path);
+        if ((bdir) && bdir->R) {
+            dir = (cdutils::DirEntry *) malloc(bdir->R);
+            memcpy(dir, bdir, bdir->R);
+        } else {
+            dir = 0;
+        }
+        if (dir) {
+            Luadirentry ldir(dir);
+            ldir.pushdestruct(L);
+        } else {
+            L->push();
+        }
+        r = 1;
+        free(datas);
+        break;
+    case CDUTILS_FINDPARENT:
+        path = L->tostring(2);
+        bdir = cd->find_parent(&datas, path);
+        if ((bdir) && bdir->R) {
+            dir = (cdutils::DirEntry *) malloc(bdir->R);
+            memcpy(dir, bdir, bdir->R);
+        } else {
+            dir = 0;
+        }
+        if (dir) {
+            Luadirentry ldir(dir);
+            ldir.pushdestruct(L);
+        } else {
+            L->push();
+        }
+        r = 1;
+        free(datas);
+        break;
+    case CDUTILS_FINDDIRENTRY:
+        adir = (cdutils::DirEntry *) LuaObject::getme(L, 2);
+        path = L->tostring(3);
+        bdir = cd->find_dir_entry(&datas, adir, path);
+        if ((bdir) && bdir->R) {
+            dir = (cdutils::DirEntry *) malloc(bdir->R);
+            memcpy(dir, bdir, bdir->R);
+        } else {
+            dir = 0;
+        }
+        if (dir) {
+            Luadirentry ldir(dir);
+            ldir.pushdestruct(L);
+        } else {
+            L->push();
+        }
+        r = 1;
+        free(datas);
+        break;
+    case CDUTILS_NEWCDFILE:
+        if (L->istable(2)) {
+            if (n <= 2) {
+                dir = (cdutils::DirEntry *) LuaObject::getme(L, 2);
+                if (n == 2)
+                    mode = L->tonumber(3);
+                cdf = new cdfile(cd, dir, mode);
+            } else {
+                invalid = true;
+            }
+        } else if (L->isnumber(2)) {
+            if (n >= 1) {
+                sector = L->tonumber(2);
+                if (n >= 2)
+                    size = L->tonumber(3);
+                if (n == 3)
+                    mode = L->tonumber(4);
+                cdf = new cdfile(cd, sector, size, mode);
+            } else {
+                invalid = true;
+            }
+        } else {
+            invalid = true;
+        }
+        if (invalid) {
+            L->error("Invalid arguments to constructor of cdfile");
+        } else {
+            Luacdfile luacdf(cdf);
+            luacdf.pushdestruct(L);
+            r = 1;
+        }
+        break;
+    case CDUTILS_UPDATESIZE:
+    case CDUTILS_UPDATESECTOR:
+	path = L->tostring(2);
+	pdir = cd->find_parent(path);
+	dir = cd->find_path(&datas, path);
+	switch (caller) {
+	case CDUTILS_UPDATESIZE:
+	    dir->Size = tolittle((Uint32) L->tonumber(3));
+	    dir->BESize = tobig((Uint32) L->tonumber(3));
+	    break;
+	case CDUTILS_UPDATESECTOR:
+	    dir->Sector = tolittle((Uint32) L->tonumber(3));
+	    dir->BESector = tobig((Uint32) L->tonumber(3));
+	    break;
+	}
+	cd->write_datas(datas, pdir.Size, GUESS, pdir.Sector);
+	free(datas);
+	break;
+    case CDUTILS_CREATESECTOR:
+	mode = L->tonumber(2);
+	sect = L->tonumber(3);
+	if (n == 3)
+	    eof = L->toboolean(4);
+	cd->create_sector(mode, sect, eof);
+	break;
+    }
+
+
+    return r;
+}
+
+int sLua_cdutils::cdutils_proceed_statics(Lua * L, int n, int caller) {
+    int r = 0;
+    Uint32 x;
+    Handle * isor = 0, * isow = 0;
+    Uint32 sector, msf, start = 150;
+    Byte m, s, f;
+
+    switch(caller) {
+    case CDUTILS_NEWCDUTILS:
+        isor = (Handle *) LuaObject::getme(L, 1);
+        if (n == 2)
+            isow = (Handle *) LuaObject::getme(L, 2);
+        {
+            Luacdutils cd(new cdutils(isor, isow));
+            cd.pushdestruct(L);
+        }
+        break;
+    case CDUTILS_SWAPWORD:
+        x = L->tonumber();
+        L->push((lua_Number) cdutils::swap_word(x));
+        r = 1;
+        break;
+    case CDUTILS_SWAPDWORD:
+        x = L->tonumber();
+        L->push((lua_Number) cdutils::swap_dword(x));
+        r = 1;
+        break;
+    case CDUTILS_FROM_BCD:
+        x = L->tonumber();
+        L->push((lua_Number) cdutils::from_BCD(x));
+        r = 1;
+        break;
+    case CDUTILS_TO_BCD:
+        x = L->tonumber();
+        L->push((lua_Number) cdutils::to_BCD(x));
+        r = 1;
+        break;
+    case CDUTILS_IS_VALID_BCD:
+        x = L->tonumber();
+        L->push(cdutils::is_valid_BCD(x));
+        r = 1;
+        break;
+    case CDUTILS_FROM_MSF:
+        if (n <= 2) {
+            msf = L->tonumber(1);
+            if (n == 2)
+                start = L->tonumber(2);
+            L->push((lua_Number) cdutils::from_MSF(msf, start));
+        } else {
+            m = L->tonumber(1);
+            s = L->tonumber(2);
+            f = L->tonumber(3);
+            if (n == 4)
+                start = L->tonumber(4);
+            L->push((lua_Number) cdutils::from_MSF(m, s, f, start));
+        }
+        r = 1;
+        break;
+    case CDUTILS_TO_MSF:
+	sector = L->tonumber(1);
+	if (n == 2)
+	    start = L->tonumber(2);
+	cdutils::to_MSF(sector, m, s, f, start);
+	msf = cdutils::to_MSF(sector, start);
+	L->push((lua_Number) msf);
+	L->push((lua_Number) m);
+	L->push((lua_Number) s);
+	L->push((lua_Number) f);
+	r = 4;
+	break;
+    }
+
+    return r;
+}
+
+
+ /***************************\
+|**  class direntry exports **|
+ \***************************/
+
+typedef cdutils::DirEntry direntry;
+
+Luadirentry::Luadirentry(cdutils::DirEntry * _dir) : dir(_dir) { }
+
+enum direntry_methods_t {
+    DIRENTRY_INDEX = 0,
+    DIRENTRY_ISHIDDEN,
+    DIRENTRY_ISDIR,
+    DIRENTRY_HASXA,
+    DIRENTRY_ISXADIR,
+    DIRENTRY_ISXAAUDIO,
+    DIRENTRY_ISXASTR,
+    DIRENTRY_ISXAXA,
+    DIRENTRY_ISXAFORM1,
+};
+
+struct lua_functypes_t direntry_methods[] = {
+    { DIRENTRY_INDEX,     "index",     1, 1, {LUA_STRING} },
+    { DIRENTRY_ISHIDDEN,  "ishidden",  0, 0, 0 },
+    { DIRENTRY_ISDIR,     "isdir",     0, 0, 0 },
+    { DIRENTRY_HASXA,     "hasxa",     0, 0, 0 },
+    { DIRENTRY_ISXADIR,   "isxadir",   0, 0, 0 },
+    { DIRENTRY_ISXAAUDIO, "isxaaudio", 0, 0, 0 },
+    { DIRENTRY_ISXASTR,   "isxastr",   0, 0, 0 },
+    { DIRENTRY_ISXAXA,    "isxaxa",    0, 0, 0 },
+    { DIRENTRY_ISXAFORM1, "isxaform1", 0, 0, 0 },
+    { -1, 0, 0, 0, 0 }
+};
+
+class sLua_direntry : public Base {
+  public:
+    DECLARE_METHOD(direntry, DIRENTRY_INDEX);
+    DECLARE_METHOD(direntry, DIRENTRY_ISHIDDEN);
+    DECLARE_METHOD(direntry, DIRENTRY_ISDIR);
+    DECLARE_METHOD(direntry, DIRENTRY_HASXA);
+    DECLARE_METHOD(direntry, DIRENTRY_ISXADIR);
+    DECLARE_METHOD(direntry, DIRENTRY_ISXAAUDIO);
+    DECLARE_METHOD(direntry, DIRENTRY_ISXASTR);
+    DECLARE_METHOD(direntry, DIRENTRY_ISXAXA);
+    DECLARE_METHOD(direntry, DIRENTRY_ISXAFORM1);
+  private:
+    static int direntry_proceed(Lua * L, int n, direntry * obj, int caller);
+};
+
+void Luadirentry::pushmembers(Lua * L) {
+    pushme(L, dir, false);
+
+    PUSH_METAMETHOD(direntry, DIRENTRY_INDEX);
+    PUSH_METHOD(direntry, DIRENTRY_ISHIDDEN);
+    PUSH_METHOD(direntry, DIRENTRY_ISDIR);
+    PUSH_METHOD(direntry, DIRENTRY_HASXA);
+    PUSH_METHOD(direntry, DIRENTRY_ISXADIR);
+    PUSH_METHOD(direntry, DIRENTRY_ISXAAUDIO);
+    PUSH_METHOD(direntry, DIRENTRY_ISXASTR);
+    PUSH_METHOD(direntry, DIRENTRY_ISXAXA);
+    PUSH_METHOD(direntry, DIRENTRY_ISXAFORM1);
+}
+
+int sLua_direntry::direntry_proceed(Lua * L, int n, direntry * dir, int caller) {
+    int r = 0, s, pad;
+    String index;
+    bool has_xa = false;
+    Byte * p;
+
+    s = 33 + dir->N;
+    if (s & 1) {
+        s++;
+        pad = 1;
+    } else {
+        pad = 0;
+    }
+    if (s != dir->R) {
+        if ((s + 14) == dir->R) {
+            p = (Byte *) dir->id + dir->N + pad;
+            if ((p[6] == 'X') && (p[7] == 'A')) {
+                has_xa = true;
+            }
+        }
+    }
+
+    switch (caller) {
+    case DIRENTRY_HASXA:
+        L->push(has_xa);
+        r = 1;
+        break;
+    case DIRENTRY_ISHIDDEN:
+        L->push(dir->Flags & 1 ? true : false);
+        r = 1;
+        break;
+    case DIRENTRY_ISDIR:
+        L->push(dir->Flags & 2 ? true : false);
+        r = 1;
+        break;
+    case DIRENTRY_ISXADIR:
+        L->push(p[4] & 0x80 ? true : false);
+        r = 1;
+        break;
+    case DIRENTRY_ISXAAUDIO:
+        L->push(p[4] & 0x40 ? true : false);
+        r = 1;
+        break;
+    case DIRENTRY_ISXASTR:
+        L->push(p[4] & 0x20 ? true : false);
+        r = 1;
+        break;
+    case DIRENTRY_ISXAXA:
+        L->push(p[4] & 0x10 ? true : false);
+        r = 1;
+        break;
+    case DIRENTRY_ISXAFORM1:
+        L->push(p[4] & 0x08 ? true : false);
+        r = 1;
+        break;
+    case DIRENTRY_INDEX:
+        index = L->tostring();
+        r = 1;
+        if (index == "R") {
+            L->push((lua_Number) dir->R);
+        } else if (index == "NExt") {
+            L->push((lua_Number) dir->NExt);
+        } else if (index == "Sector") {
+            L->push((lua_Number) dir->Sector);
+        } else if (index == "Size") {
+            L->push((lua_Number) dir->Size);
+        } else if (index == "Year") {
+            L->push((lua_Number) dir->Year);
+        } else if (index == "Month") {
+            L->push((lua_Number) dir->Month);
+        } else if (index == "Day") {
+            L->push((lua_Number) dir->Day);
+        } else if (index == "Hour") {
+            L->push((lua_Number) dir->Hour);
+        } else if (index == "Minute") {
+            L->push((lua_Number) dir->Minute);
+        } else if (index == "Second") {
+            L->push((lua_Number) dir->Second);
+        } else if (index == "Offset") {
+            L->push((lua_Number) dir->Offset);
+        } else if (index == "Flags") {
+            L->push((lua_Number) dir->Flags);
+        } else if (index == "HandleUnit") {
+            L->push((lua_Number) dir->HandleUnit);
+        } else if (index == "HandleGap") {
+            L->push((lua_Number) dir->HandleGap);
+        } else if (index == "VolSeq") {
+            L->push((lua_Number) dir->VolSeq);
+        } else if (index == "N") {
+            L->push((lua_Number) dir->N);
+        } else if (index == "id") {
+            char pbuf[256];
+            memcpy(pbuf, dir->id, dir->N);
+            pbuf[dir->N] = 0;
+            L->push(pbuf, dir->N);
+        } else {
+            L->push();
+        }
+    }
+
+    return r;
+}
+
+
+ /***************************\
+|**  class direntry exports **|
+ \***************************/
+
+typedef isobuilder::Date cddate;
+
+Luacddate::Luacddate(isobuilder::Date * _date) : date(_date) { }
+
+enum cddate_methods_t {
+    CDDATE_INDEX = 0,
+    CDDATE_NEWINDEX,
+};
+
+enum cddate_functions_t {
+    CDDATE_NEWCDDATE = 0,
+};
+
+struct lua_functypes_t cddate_methods[] = {
+    { CDDATE_INDEX,    "index",    1, 1, {LUA_STRING} },
+    { CDDATE_NEWINDEX, "newindex", 2, 2, {LUA_STRING, LUA_NUMBER} },
+    { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t cddate_functions[] = {
+    { CDDATE_NEWCDDATE, "cddate", 0, 0, 0 },
+    { -1, 0, 0, 0, 0 }
+};
+
+class sLua_cddate : public Base {
+  public:
+    DECLARE_METHOD(cddate, CDDATE_INDEX);
+    DECLARE_METHOD(cddate, CDDATE_NEWINDEX);
+    DECLARE_FUNCTION(cddate, CDDATE_NEWCDDATE);
+  private:
+    static int cddate_proceed(Lua * L, int n, cddate * obj, int caller);
+    static int cddate_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luacddate::pushmembers(Lua * L) {
+    pushme(L, date, false);
+
+    PUSH_METAMETHOD(cddate, CDDATE_INDEX);
+    PUSH_METAMETHOD(cddate, CDDATE_NEWINDEX);
+}
+
+void Luacddate::pushstatics(Lua * L) throw (GeneralException) {
+    CHECK_METHODS(cddate);
+    CHECK_FUNCTIONS(cddate);
+
+    PUSH_FUNCTION(cddate, CDDATE_NEWCDDATE);
+}
+
+int sLua_cddate::cddate_proceed(Lua * L, int n, cddate * date, int caller) {
+    int r, value;
+    String key;
+
+    switch (caller) {
+    case CDDATE_INDEX:
+        key = L->tostring(2);
+        r = 1;
+        if        (key == "year") {
+            L->push((lua_Number) date->year);
+        } else if (key == "month") {
+            L->push((lua_Number) date->month);
+        } else if (key == "day") {
+            L->push((lua_Number) date->day);
+        } else if (key == "hour") {
+            L->push((lua_Number) date->hour);
+        } else if (key == "minute") {
+            L->push((lua_Number) date->minute);
+        } else if (key == "second") {
+            L->push((lua_Number) date->second);
+        } else if (key == "hundredths") {
+            L->push((lua_Number) date->hundredths);
+        } else if (key == "offset") {
+            L->push((lua_Number) date->offset);
+        } else {
+            L->error("Key " + key + " not in class Date");
+        }
+        break;
+    case CDDATE_NEWINDEX:
+	r = 0;
+        key = L->tostring(2);
+        value = L->tonumber(3);
+        if (key == "year") {
+            date->year = value;
+        } else if (key == "month") {
+            date->month = value;
+        } else if (key == "day") {
+            date->day = value;
+        } else if (key == "hour") {
+            date->hour = value;
+        } else if (key == "minute") {
+            date->minute = value;
+        } else if (key == "second") {
+            date->second = value;
+        } else if (key == "hundredths") {
+            date->hundredths = value;
+        } else if (key == "offset") {
+            date->offset = value;
+        } else {
+            L->error("Key " + key + " not in class Date");
+        }
+        break;
+    }
+
+    return r;
+}
+
+int sLua_cddate::cddate_proceed_statics(Lua * L, int n, int caller) {
+    int r = 0;
+
+    switch (caller) {
+    case CDDATE_NEWCDDATE:
+        {
+            Luacddate t(new isobuilder::Date());
+            t.pushdestruct(L);
+        }
+    }
+
+    return r;
+}
+
+ /**********************\
+|**  class PVD exports **|
+ \**********************/
+
+typedef isobuilder::PVD PVD;
+
+LuaPVD::LuaPVD(struct isobuilder::PVD * _pvd) : pvd(_pvd) { }
+
+enum PVD_methods_t {
+    PVD_INDEX = 0,
+    PVD_NEWINDEX,
+};
+
+enum PVD_functions_t {
+    PVD_NEWPVD = 0,
+};
+
+struct lua_functypes_t PVD_methods[] = {
+    { PVD_INDEX,    "index",    1, 1, {LUA_ANY} },
+    { PVD_NEWINDEX, "newindex", 2, 2, {LUA_ANY, LUA_ANY} },
+    { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t PVD_functions[] = {
+    { PVD_NEWPVD,   "PVD",      0, 0, 0 },
+    { -1, 0, 0, 0, 0 }
+};
+
+class sLua_PVD : public Base {
+  public:
+    DECLARE_METHOD(PVD, PVD_INDEX);
+    DECLARE_METHOD(PVD, PVD_NEWINDEX);
+
+    DECLARE_FUNCTION(PVD, PVD_NEWPVD);
+
+  private:
+    static int PVD_proceed(Lua * L, int n, PVD * obj, int caller);
+    static int PVD_proceed_statics(Lua * L, int n, int caller);
+};
+
+void LuaPVD::pushmembers(Lua * L) {
+    pushme(L, pvd, false);
+
+    PUSH_METAMETHOD(PVD, PVD_INDEX);
+    PUSH_METAMETHOD(PVD, PVD_NEWINDEX);
+}
+
+void LuaPVD::pushstatics(Lua * L) throw (GeneralException) {
+    CHECK_METHODS(PVD);
+    CHECK_FUNCTIONS(PVD);
+
+    PUSH_FUNCTION(PVD, PVD_NEWPVD);
+}
+
+int sLua_PVD::PVD_proceed(Lua * L, int n, PVD * pvd, int caller) {
+    int r = 0, key_i = 0, value_i;
+    String key_s, value_s;
+    cddate * value_date;
+    bool invalid = false, keyisstring;
+
+    if (L->isnumber(2)) {
+        keyisstring = false;
+        key_i = L->tonumber(2);
+    } else {
+        keyisstring = true;
+        key_s = L->tostring(2);
+    }
+    
+    switch (caller) {
+    case PVD_INDEX:
+        r = 1;
+        if        (keyisstring && (key_s == "sysid")) {
+            L->push(pvd->sysid);
+        } else if (keyisstring && (key_s == "volid")) {
+            L->push(pvd->volid);
+        } else if (keyisstring && (key_s == "volsetid")) {
+            L->push(pvd->volsetid);
+        } else if (keyisstring && (key_s == "pubid")) {
+            L->push(pvd->pubid);
+        } else if (keyisstring && (key_s == "prepid")) {
+            L->push(pvd->prepid);
+        } else if (keyisstring && (key_s == "appid")) {
+            L->push(pvd->appid);
+        } else if (keyisstring && (key_s == "copyright")) {
+            L->push(pvd->copyright);
+        } else if (keyisstring && (key_s == "abstract")) {
+            L->push(pvd->abstract);
+        } else if (keyisstring && (key_s == "biblio")) {
+            L->push(pvd->biblio);
+        } else if (keyisstring && (key_s == "volcreat")) {
+            {
+                Luacddate date(&pvd->volcreat);
+                date.push(L);
+            }
+        } else if (keyisstring && (key_s == "modif")) {
+            {
+                Luacddate date(&pvd->modif);
+                date.push(L);
+            }
+        } else if (keyisstring && (key_s == "volexp")) {
+            {
+                Luacddate date(&pvd->volexp);
+                date.push(L);
+            }
+        } else if (keyisstring && (key_s == "voleff")) {
+            {
+                Luacddate date(&pvd->voleff);
+                date.push(L);
+            }
+        } else if (!keyisstring && (key_i >= 0) && (key_i < 512)) {
+            L->push((lua_Number) pvd->appdata[key_i]);
+        } else {
+            invalid = true;
+        }
+        break;
+    case PVD_NEWINDEX:
+        if        (keyisstring && (key_s == "sysid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->sysid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "volid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->volid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "volsetid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->volsetid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "pubid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->pubid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "prepid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->prepid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "appid")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->appid = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "copyright")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->copyright = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "abstract")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->abstract = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "biblio")) {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                pvd->biblio = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "volcreat")) {
+            if (L->islightuserdata(3)) {
+                value_date = (cddate *) LuaObject::getme(L, 3);
+                pvd->volcreat = *value_date;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "modif")) {
+            if (L->islightuserdata(3)) {
+                value_date = (cddate *) LuaObject::getme(L, 3);
+                pvd->modif = *value_date;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "volexp")) {
+            if (L->islightuserdata(3)) {
+                value_date = (cddate *) LuaObject::getme(L, 3);
+                pvd->volexp = *value_date;
+            } else {
+                invalid = true;
+            }
+        } else if (keyisstring && (key_s == "voleff")) {
+            if (L->islightuserdata(3)) {
+                value_date = (cddate *) LuaObject::getme(L, 3);
+                pvd->voleff = *value_date;
+            } else {
+                invalid = true;
+            }
+        } else if (!keyisstring && (key_i >= 0) && (key_i < 512)) {
+            if (L->isnumber(3)) {
+                pvd->appdata[key_i] = L->tonumber(3);
+            } else {
+                invalid = true;
+            }
+        } else {
+            invalid = true;
+        }
+        break;
+    }
+
+    if (invalid) {
+        L->error("Invalid usage of structure PVD");
+    }
+
+    return r;
+}
+
+int sLua_PVD::PVD_proceed_statics(Lua * L, int n, int caller) {
+    int r = 0;
+
+    switch (caller) {
+    case PVD_NEWPVD:
+        r = 1;
+        {
+            LuaPVD pvd((PVD *) malloc(sizeof(PVD)));
+            pvd.pushdestruct(L);
+        }
+        break;
+    }
+
+    return r;
+}
+
+
+ /**************************\
+|**  class DirTree exports **|
+ \**************************/
+
+typedef isobuilder::DirTree DirTree;
+
+LuaDirTree::LuaDirTree(isobuilder::DirTree * _dir) : dir(_dir) { }
+
+enum DirTree_methods_t {
+    DIRTREE_INDEX = 0,
+    DIRTREE_NEWINDEX,
+    DIRTREE_FROMDIR,
+    DIRTREE_SETBASICSXA,
+    DIRTREE_FIND,
+};
+
+enum DirTree_functions_t {
+    DIRTREE_NEWDIRTREE = 0,
+};
+
+struct lua_functypes_t DirTree_methods[] = {
+    { DIRTREE_INDEX,       "index",       1, 1, {LUA_STRING} },
+    { DIRTREE_NEWINDEX,    "newindex",    2, 2, {LUA_STRING, LUA_ANY} },
+    { DIRTREE_FROMDIR,     "fromdir",     1, 1, {LUA_OBJECT} },
+    { DIRTREE_SETBASICSXA, "setbasicsxa", 0, 0, 0 },
+    { DIRTREE_FIND,        "find",        1, 1, {LUA_STRING} },
+    { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t DirTree_functions[] = {
+    { DIRTREE_NEWDIRTREE, "DirTree", 1, 2, {LUA_OBJECT, LUA_BOOLEAN} },
+    { -1, 0, 0, 0, 0 }
+};
+
+class sLua_DirTree : public Base {
+  public:
+    DECLARE_METHOD(DirTree, DIRTREE_INDEX);
+    DECLARE_METHOD(DirTree, DIRTREE_NEWINDEX);
+    DECLARE_METHOD(DirTree, DIRTREE_FROMDIR);
+    DECLARE_METHOD(DirTree, DIRTREE_SETBASICSXA);
+    DECLARE_METHOD(DirTree, DIRTREE_FIND);
+
+    DECLARE_FUNCTION(DirTree, DIRTREE_NEWDIRTREE);
+  private:
+    static int DirTree_proceed(Lua * L, int n, DirTree * obj, int caller);
+    static int DirTree_proceed_statics(Lua * L, int n, int caller);
+};
+
+void LuaDirTree::pushmembers(Lua * L) {
+    pushme(L, dir);
+
+    PUSH_METAMETHOD(DirTree, DIRTREE_INDEX);
+    PUSH_METAMETHOD(DirTree, DIRTREE_NEWINDEX);
+
+    PUSH_METHOD(DirTree, DIRTREE_FROMDIR);
+    PUSH_METHOD(DirTree, DIRTREE_SETBASICSXA);
+    PUSH_METHOD(DirTree, DIRTREE_FIND);
+}
+
+void LuaDirTree::pushstatics(Lua * L) throw (GeneralException) {
+    CHECK_METHODS(DirTree);
+    CHECK_FUNCTIONS(DirTree);
+
+    PUSH_FUNCTION(DirTree, DIRTREE_NEWDIRTREE);
+}
+
+int sLua_DirTree::DirTree_proceed(Lua * L, int n, DirTree * dir, int caller) {
+    int r = 0, value_i;
+    direntry * dirent;
+    DirTree * rdir;
+    String f, key, value_s;
+    bool invalid = false, value_b;
+    cddate * value_date;
+
+    switch (caller) {
+    case DIRTREE_FROMDIR:
+        dirent = (direntry *) LuaObject::getme(L, 2);
+        dir->fromdir(dirent);
+        break;
+    case DIRTREE_SETBASICSXA:
+        dir->setbasicsxa();
+        break;
+    case DIRTREE_FIND:
+        f = L->tostring(2);
+        rdir = dir->Find(f);
+        if (rdir) {
+            LuaDirTree dirt(rdir);
+            dirt.push(L);
+        } else {
+            L->push();
+        }
+        break;
+    case DIRTREE_INDEX:
+        key = L->tostring(2);
+        r = 1;
+        if        (key == "sector") {
+            L->push((lua_Number) dir->sector);
+        } else if (key == "size") {
+            L->push((lua_Number) dir->size);
+        } else if (key == "hidden") {
+            L->push(dir->hidden);
+        } else if (key == "hardhide") {
+            L->push(dir->hardhide);
+        } else if (key == "name") {
+            L->push(dir->name);
+        } else if (key == "creation") {
+            Luacddate date(&dir->creation);
+            date.push(L);
+        } else if (key == "have_xa") {
+            L->push(dir->have_xa);
+        } else if (key == "xa_dir") {
+            L->push(dir->xa_dir);
+        } else if (key == "xa_audio") {
+            L->push(dir->xa_audio);
+        } else if (key == "xa_str") {
+            L->push(dir->xa_str);
+        } else if (key == "xa_xa") {
+            L->push(dir->xa_xa);
+        } else if (key == "xa_form1") {
+            L->push(dir->xa_form1);
+        } else if (key == "mode") {
+            L->push((lua_Number) dir->mode);
+        } else if (key == "father") {
+            LuaDirTree tdir(dir->Father());
+            tdir.push(L);
+        } else if (key == "child") {
+            LuaDirTree tdir(dir->Child());
+            tdir.push(L);
+        } else if (key == "brother") {
+            LuaDirTree tdir(dir->Brother());
+            tdir.push(L);
+        } else if (key == "isdir") {
+            L->push(dir->isdir());
+        } else {
+            invalid = true;
+        }
+        break;
+    case DIRTREE_NEWINDEX:
+        key = L->tostring(2);
+        if        (key == "sector") {
+            if (L->isnumber(3)) {
+                value_i = L->tonumber(3);
+                dir->sector = value_i;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "size") {
+            if (L->isnumber(3)) {
+                value_i = L->tonumber(3);
+                dir->size = value_i;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "hidden") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->hidden = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "hardhide") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->hardhide = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "name") {
+            if (L->isstring(3)) {
+                value_s = L->tostring(3);
+                dir->name = value_s;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "creation") {
+            if (L->islightuserdata(3)) {
+                value_date = (cddate *) LuaObject::getme(L, 3);
+                dir->creation = *value_date;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "have_xa") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->have_xa = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "xa_dir") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->xa_dir = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "xa_audio") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->xa_audio = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "xa_str") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->xa_str = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "xa_xa") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->xa_xa = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "xa_form1") {
+            if (L->isboolean(3)) {
+                value_b = L->toboolean(3);
+                dir->xa_form1 = value_b;
+            } else {
+                invalid = true;
+            }
+        } else if (key == "mode") {
+            if (L->isnumber(3)) {
+                value_i = L->tonumber(3);
+                dir->mode = value_i;
+            } else {
+                invalid = true;
+            }
+        } else {
+            invalid = true;
+        }
+        break;
+    }
+
+    if (invalid) {
+        L->error("Invalid usage of structure DirTree");
+    }
+
+    return r;
+}
+
+int sLua_DirTree::DirTree_proceed_statics(Lua * L, int n, int caller) {
+    int r;
+    DirTree * father;
+    bool dir = true;
+
+    switch (caller) {
+    case DIRTREE_NEWDIRTREE:
+        father = (DirTree *) LuaObject::getme(L, 1);
+        if (n == 2)
+            dir = L->toboolean(2);
+        {
+            LuaDirTree dirt(new DirTree(father, dir));
+            dirt.pushdestruct(L);
+        }
+        break;
+    }
+
+    return r;
+}
+
+
+ /*****************************\
+|**  class isobuilder exports **|
+ \*****************************/
+
+Luaisobuilder::Luaisobuilder(isobuilder * _iso) : iso(_iso) { }
+
+enum isobuilder_methods_t {
+    ISOBUILDER_FOREWORD = 0,
+    ISOBUILDER_FOREWORD_HANDLE,
+    ISOBUILDER_FOREWORD_ARRAY,
+    ISOBUILDER_GETDISPSECT,
+    ISOBUILDER_PUTFILE,
+    ISOBUILDER_PUTDATAS,
+    ISOBUILDER_CREATESECTOR,
+    ISOBUILDER_SETEOF,
+    ISOBUILDER_CLEAREOF,
+    ISOBUILDER_SETBASICS,
+    ISOBUILDER_CREATEDIR,
+    ISOBUILDER_CREATEFILE,
+    ISOBUILDER_COPYDIR,
+    ISOBUILDER_CLOSE,
+};
+
+enum isobuilder_functions_t {
+    ISOBUILDER_NEWISOBUILDER = 0,
+    ISOBUILDER_CREATEPVD_HANDLE,
+    ISOBUILDER_CREATEPVD,
+    ISOBUILDER_CREATEPVD_ARRAY,
+};
+
+struct lua_functypes_t isobuilder_methods[] = {
+    { ISOBUILDER_FOREWORD,          "foreword",          1, 1, {LUA_OBJECT} },
+    { ISOBUILDER_FOREWORD_HANDLE,   "foreword_handle",   1, 2, {LUA_OBJECT, LUA_NUMBER} },
+    { ISOBUILDER_FOREWORD_ARRAY,    "foreword_array",    1, 2, {LUA_TABLE, LUA_NUMBER} },
+    { ISOBUILDER_GETDISPSECT,       "getdispsect",       0, 0, 0},
+    { ISOBUILDER_PUTFILE,           "putfile",           1, 3, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER} },
+    { ISOBUILDER_PUTDATAS,          "putdatas",          2, 4, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+    { ISOBUILDER_CREATESECTOR,      "createsector",      1, 3, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER} },
+    { ISOBUILDER_SETEOF,            "setEOF",            0, 0, 0 },
+    { ISOBUILDER_CLEAREOF,          "clearEOF",          0, 0, 0 },
+    { ISOBUILDER_SETBASICS,         "setbasics",         1, 5, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
+    { ISOBUILDER_CREATEDIR,         "createdir",         2, 5, {LUA_OBJECT, LUA_STRING, LUA_NUMBER, LUA_OBJECT, LUA_NUMBER} },
+    { ISOBUILDER_CREATEFILE,        "createfile",        3, 5, {LUA_OBJECT, LUA_STRING, LUA_OBJECT, LUA_OBJECT, LUA_NUMBER} },
+    { ISOBUILDER_COPYDIR,           "copydir",           3, 4, {LUA_OBJECT, LUA_OBJECT, LUA_OBJECT, LUA_NUMBER} },
+    { ISOBUILDER_CLOSE,             "close",             0, 3, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER} },
+    { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t isobuilder_functions[] = {
+    { ISOBUILDER_NEWISOBUILDER,     "isobuilder",        1, 2, {LUA_OBJECT, LUA_NUMBER} },
+    { ISOBUILDER_CREATEPVD_HANDLE,  "createpvd_handle",  1, 1, {LUA_OBJECT} },
+    { ISOBUILDER_CREATEPVD,         "createpvd",         1, 1, {LUA_OBJECT} },
+    { ISOBUILDER_CREATEPVD_ARRAY,   "createpvd_array",   1, 1, {LUA_TABLE} },
+    { -1, 0, 0, 0, 0 }
+};
+
+class sLua_isobuilder : public Base {
   public:
-      Luacdfile(cdfile * h) : LuaHandle(h) {}
+    DECLARE_METHOD(isobuilder, ISOBUILDER_FOREWORD);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_FOREWORD_HANDLE);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_FOREWORD_ARRAY);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_GETDISPSECT);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_PUTFILE);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_PUTDATAS);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_CREATESECTOR);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_SETEOF);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_CLEAREOF);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_SETBASICS);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_CREATEDIR);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_CREATEFILE);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_COPYDIR);
+    DECLARE_METHOD(isobuilder, ISOBUILDER_CLOSE);
+
+    DECLARE_FUNCTION(isobuilder, ISOBUILDER_NEWISOBUILDER);
+    DECLARE_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_HANDLE);
+    DECLARE_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD);
+    DECLARE_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_ARRAY);
+
+  private:
+    static int isobuilder_proceed(Lua * L, int n, isobuilder * obj, int caller);
+    static int isobuilder_proceed_statics(Lua * L, int n, int caller);
 };
-
-enum cdutils_methods_t {
-    CDUTILS_SETISOW = 0,
-    CDUTILS_GUESSTYPE,
-    CDUTILS_SECTORSEEK,
-    CDUTILS_READSECTOR,
-    CDUTILS_READDATAS,
-    CDUTILS_READFILE,
-    CDUTILS_WRITESECTOR,
-    CDUTILS_WRITEDATAS,
-    CDUTILS_WRITEFILE,
-    CDUTILS_GETISOINFOS,
-    CDUTILS_GETPTINFOS,
-    CDUTILS_FINDPATH,
-    CDUTILS_FINDPARENT,
-    CDUTILS_FINDDIRENTRY,
-    CDUTILS_NEWCDFILE,
-    CDUTILS_UPDATESIZE,
-    CDUTILS_UPDATESECTOR,
-    CDUTILS_CREATESECTOR,
-};
-
-enum cdutils_functions_t {
-    CDUTILS_NEWCDUTILS = 0,
-    CDUTILS_SWAPWORD,
-    CDUTILS_SWAPDWORD,
-    CDUTILS_FROM_BCD,
-    CDUTILS_TO_BCD,
-    CDUTILS_IS_VALID_BCD,
-    CDUTILS_FROM_MSF,
-    CDUTILS_TO_MSF,
-};
-
-struct lua_functypes_t cdutils_methods[] = {
-    { CDUTILS_SETISOW,      "set_iso_w",    1, 1, {LUA_OBJECT} },
-    { CDUTILS_GUESSTYPE,    "guessmode",    0, 1, {LUA_NUMBER} },
-    { CDUTILS_SECTORSEEK,   "sectorseek",   1, 1, {LUA_NUMBER} },
-    { CDUTILS_READSECTOR,   "readsector",   0, 2, {LUA_NUMBER, LUA_NUMBER} },
-    { CDUTILS_READDATAS,    "readdatas",    1, 3, {LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
-    { CDUTILS_READFILE,     "readfile",     2, 4, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
-    { CDUTILS_WRITESECTOR,  "writesector",  1, 3, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER} },
-    { CDUTILS_WRITEDATAS,   "writedatas",   2, 4, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
-    { CDUTILS_WRITEFILE,    "writefile",    1, 4, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
-    { CDUTILS_GETISOINFOS,  "getisoinfos",  0, 0, 0 },
-    { CDUTILS_GETPTINFOS,   "getptinfos",   0, 0, 0 },
-    { CDUTILS_FINDPATH,     "findpath",     1, 1, {LUA_STRING} },
-    { CDUTILS_FINDPARENT,   "findparent",   1, 1, {LUA_STRING} },
-    { CDUTILS_FINDDIRENTRY, "finddirentry", 2, 2, {LUA_OBJECT, LUA_STRING} },
-    { CDUTILS_NEWCDFILE,    "cdfile",       1, 3, {LUA_ANY, LUA_NUMBER, LUA_NUMBER} },
-    { CDUTILS_UPDATESIZE,   "updatesize",   2, 2, {LUA_STRING, LUA_NUMBER} },
-    { CDUTILS_UPDATESECTOR, "updatesector", 2, 2, {LUA_STRING, LUA_NUMBER} },
-    { CDUTILS_CREATESECTOR, "createsector", 2, 3, {LUA_NUMBER, LUA_NUMBER, LUA_BOOLEAN} },
-    { -1, 0, 0, 0, 0 }
-};
-
-struct lua_functypes_t cdutils_functions[] = {
-    { CDUTILS_NEWCDUTILS,   "cdutils" ,     1, 2, {LUA_OBJECT, LUA_OBJECT} },
-    { CDUTILS_SWAPWORD,     "swapword",     1, 1, {LUA_NUMBER} },
-    { CDUTILS_SWAPDWORD,    "swapdword",    1, 1, {LUA_NUMBER} },
-    { CDUTILS_FROM_BCD,     "from_BCD",     1, 1, {LUA_NUMBER} },
-    { CDUTILS_TO_BCD,       "to_BCD",       1, 1, {LUA_NUMBER} },
-    { CDUTILS_IS_VALID_BCD, "is_valid_BCD", 1, 1, {LUA_NUMBER} },
-    { CDUTILS_FROM_MSF,     "from_MSF",     1, 4, {LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
-    { CDUTILS_TO_MSF,       "to_MSF",       1, 2, {LUA_NUMBER, LUA_NUMBER} },
-    { -1, 0, 0, 0, 0 }
-};
-
-class sLua_cdutils : public Base {
-  public:
-    DECLARE_METHOD(cdutils, CDUTILS_SETISOW);
-    DECLARE_METHOD(cdutils, CDUTILS_GUESSTYPE);
-    DECLARE_METHOD(cdutils, CDUTILS_SECTORSEEK);
-    DECLARE_METHOD(cdutils, CDUTILS_READSECTOR);
-    DECLARE_METHOD(cdutils, CDUTILS_READDATAS);
-    DECLARE_METHOD(cdutils, CDUTILS_READFILE);
-    DECLARE_METHOD(cdutils, CDUTILS_WRITESECTOR);
-    DECLARE_METHOD(cdutils, CDUTILS_WRITEDATAS);
-    DECLARE_METHOD(cdutils, CDUTILS_WRITEFILE);
-    DECLARE_METHOD(cdutils, CDUTILS_GETISOINFOS);
-    DECLARE_METHOD(cdutils, CDUTILS_GETPTINFOS);
-    DECLARE_METHOD(cdutils, CDUTILS_FINDPATH);
-    DECLARE_METHOD(cdutils, CDUTILS_FINDPARENT);
-    DECLARE_METHOD(cdutils, CDUTILS_FINDDIRENTRY);
-    DECLARE_METHOD(cdutils, CDUTILS_NEWCDFILE);
-    DECLARE_METHOD(cdutils, CDUTILS_UPDATESIZE);
-    DECLARE_METHOD(cdutils, CDUTILS_UPDATESECTOR);
-    DECLARE_METHOD(cdutils, CDUTILS_CREATESECTOR);
-
-    DECLARE_FUNCTION(cdutils, CDUTILS_NEWCDUTILS);
-    DECLARE_FUNCTION(cdutils, CDUTILS_SWAPWORD);
-    DECLARE_FUNCTION(cdutils, CDUTILS_SWAPDWORD);
-    DECLARE_FUNCTION(cdutils, CDUTILS_FROM_BCD);
-    DECLARE_FUNCTION(cdutils, CDUTILS_TO_BCD);
-    DECLARE_FUNCTION(cdutils, CDUTILS_IS_VALID_BCD);
-    DECLARE_FUNCTION(cdutils, CDUTILS_FROM_MSF);
-    DECLARE_FUNCTION(cdutils, CDUTILS_TO_MSF);
-
-  private:
-    static int cdutils_proceed(Lua * L, int n, cdutils * obj, int caller);
-    static int cdutils_proceed_statics(Lua * L, int n, int caller);
-};
-
-void Luacdutils::pushmembers(Lua * L) {
-    pushme(L, cd);
-
-    PUSH_METHOD(cdutils, CDUTILS_SETISOW);
-    PUSH_METHOD(cdutils, CDUTILS_GUESSTYPE);
-    PUSH_METHOD(cdutils, CDUTILS_SECTORSEEK);
-    PUSH_METHOD(cdutils, CDUTILS_READSECTOR);
-    PUSH_METHOD(cdutils, CDUTILS_READDATAS);
-    PUSH_METHOD(cdutils, CDUTILS_READFILE);
-    PUSH_METHOD(cdutils, CDUTILS_WRITESECTOR);
-    PUSH_METHOD(cdutils, CDUTILS_WRITEDATAS);
-    PUSH_METHOD(cdutils, CDUTILS_WRITEFILE);
-    PUSH_METHOD(cdutils, CDUTILS_GETISOINFOS);
-    PUSH_METHOD(cdutils, CDUTILS_GETPTINFOS);
-    PUSH_METHOD(cdutils, CDUTILS_FINDPATH);
-    PUSH_METHOD(cdutils, CDUTILS_FINDPARENT);
-    PUSH_METHOD(cdutils, CDUTILS_FINDDIRENTRY);
-    PUSH_METHOD(cdutils, CDUTILS_NEWCDFILE);
-    PUSH_METHOD(cdutils, CDUTILS_UPDATESIZE);
-    PUSH_METHOD(cdutils, CDUTILS_UPDATESECTOR);
-    PUSH_METHOD(cdutils, CDUTILS_CREATESECTOR);
-}
-
-void Luacdutils::pushstatics(Lua * L) throw (GeneralException) {
-    CHECK_METHODS(cdutils);
-    CHECK_FUNCTIONS(cdutils);
-
-    PUSH_FUNCTION(cdutils, CDUTILS_NEWCDUTILS);
-    PUSH_FUNCTION(cdutils, CDUTILS_SWAPWORD);
-    PUSH_FUNCTION(cdutils, CDUTILS_SWAPDWORD);
-    PUSH_FUNCTION(cdutils, CDUTILS_FROM_BCD);
-    PUSH_FUNCTION(cdutils, CDUTILS_TO_BCD);
-    PUSH_FUNCTION(cdutils, CDUTILS_IS_VALID_BCD);
-    PUSH_FUNCTION(cdutils, CDUTILS_FROM_MSF);
-    PUSH_FUNCTION(cdutils, CDUTILS_TO_MSF);
-
-    L->push("MODE0");
-    L->push((lua_Number) MODE0);
-    L->setvar();
-
-    L->push("MODE1");
-    L->push((lua_Number) MODE1);
-    L->setvar();
-
-    L->push("MODE2");
-    L->push((lua_Number) MODE2);
-    L->setvar();
-
-    L->push("MODE2_FORM1");
-    L->push((lua_Number) MODE2_FORM1);
-    L->setvar();
-
-    L->push("MODE2_FORM2");
-    L->push((lua_Number) MODE2_FORM2);
-    L->setvar();
-
-    L->push("MORE_RAW");
-    L->push((lua_Number) MODE_RAW);
-    L->setvar();
-
-    L->push("GUESS");
-    L->push((lua_Number) GUESS);
-    L->setvar();
-
-    int i;
-
-    L->push("sec_sizes");
-    L->newtable();
-    for (i = 0; i <= GUESS; i++) {
-        L->push((lua_Number) i);
-        L->push((lua_Number) sec_sizes[i]);
-        L->settable();
-    }
-    L->setvar();
-
-    L->push("sec_offsts");
-    L->newtable();
-    for (i = 0; i <= GUESS; i++) {
-        L->push((lua_Number) i);
-        L->push((lua_Number) sec_offsts[i]);
-        L->settable();
-    }
-    L->setvar();
-
-    L->push("sec_modes");
-    L->newtable();
-    for (i = 0; i <= GUESS; i++) {
-        L->push((lua_Number) i);
-        L->push(sec_modes[i]);
-        L->settable();
-    }
-    L->setvar();
-}
-
-int sLua_cdutils::cdutils_proceed(Lua * L, int n, cdutils * cd, int caller) {
-    int r = 0, sect = -1, mode = GUESS, size = -1, i;
-    Handle * h;
-    Byte sdatas[2352], * datas;
-    String path;
-    cdutils::DirEntry * dir, * bdir, * adir, pdir;
-    bool invalid = false, eof = false;
-    int sector;
-    cdfile * cdf;
-
-    switch(caller) {
-    case CDUTILS_SETISOW:
-        h = (Handle *) LuaObject::getme(L, 2);
-        cd->set_iso_w(h);
-        break;
-    case CDUTILS_GUESSTYPE:
-        if (n == 1) {
-            sect = L->tonumber(2);
-        }
-        L->push((lua_Number) cd->guess_type(sect));
-        r = 1;
-        break;
-    case CDUTILS_SECTORSEEK:
-        sect = L->tonumber(2);
-        cd->sector_seek(sect);
-        break;
-    case CDUTILS_READSECTOR:
-        if (n >= 1)
-            sect = L->tonumber(2);
-        if (n == 2)
-            mode = L->tonumber(3);
-        size = cd->read_sector(sdatas, mode, sect);
-        L->newtable();
-        for (i = 0; i < size; i++) {
-            L->push((lua_Number) i);
-            L->push((lua_Number) sdatas[i]);
-            L->settable();
-        }
-        r = 1;
-        break;
-    case CDUTILS_READDATAS:
-        size = L->tonumber(2);
-        if (n >= 2)
-            sect = L->tonumber(3);
-        if (n == 3)
-            mode = L->tonumber(3);
-        datas = (Byte *) malloc(size);
-        cd->read_datas(datas, size, mode, sect);
-        L->newtable();
-        for (i = 0; i < size; i++) {
-            L->push((lua_Number) i);
-            L->push((lua_Number) datas[i]);
-            L->settable();
-        }
-        r = 1;
-        free(datas);
-        break;
-    case CDUTILS_READFILE:
-        h = (Handle *) LuaObject::getme(L, 2);
-        size = L->tonumber(5);
-        if (n >= 3)
-            sect = L->tonumber(4);
-        if (n == 4)
-            mode = L->tonumber(5);
-        cd->read_file(h, size, mode, sect);
-        break;
-    case CDUTILS_WRITESECTOR:
-        if (n >= 2)
-            sect = L->tonumber(3);
-        if (n == 3)
-            mode = L->tonumber(4);
-        for (i = 0; i < 2352; i++) {
-            L->push((lua_Number) i);
-            L->gettable(2);
-            sdatas[i] = L->tonumber();
-            L->pop();
-        }
-        cd->write_sector(datas, mode, sect);
-        break;
-    case CDUTILS_WRITEDATAS:
-        size = L->tonumber(3);
-        if (n >= 3)
-            sect = L->tonumber(4);
-        if (n == 4)
-            mode = L->tonumber(5);
-        datas = (Byte *) malloc(size);
-
-        for (i = 0; i < size; i++) {
-            L->push((lua_Number) i);
-            L->gettable(2);
-            sdatas[i] = L->tonumber();
-            L->pop();
-        }
-        cd->write_datas(datas, size, mode, sect);
-        free(datas);
-        break;
-    case CDUTILS_WRITEFILE:
-        h = (Handle *) LuaObject::getme(L, 2);
-        if (n >= 2)
-            size = L->tonumber(3);
-        if (n >= 3)
-            sect = L->tonumber(4);
-        if (n == 4)
-            mode = L->tonumber(5);
-        cd->write_file(h, size, mode, sect);
-        break;
-    case CDUTILS_GETISOINFOS:
-        L->push((lua_Number) cd->get_iso_infos());
-        r = 1;
-        break;
-    case CDUTILS_GETPTINFOS:
-        L->push((lua_Number) cd->get_pt_infos());
-        r = 1;
-        break;
-    case CDUTILS_FINDPATH:
-        path = L->tostring(2);
-        bdir = cd->find_path(&datas, path);
-        if ((bdir) && bdir->R) {
-            dir = (cdutils::DirEntry *) malloc(bdir->R);
-            memcpy(dir, bdir, bdir->R);
-        } else {
-            dir = 0;
-        }
-        if (dir) {
-            Luadirentry ldir(dir);
-            ldir.pushdestruct(L);
-        } else {
-            L->push();
-        }
-        r = 1;
-        free(datas);
-        break;
-    case CDUTILS_FINDPARENT:
-        path = L->tostring(2);
-        bdir = cd->find_parent(&datas, path);
-        if ((bdir) && bdir->R) {
-            dir = (cdutils::DirEntry *) malloc(bdir->R);
-            memcpy(dir, bdir, bdir->R);
-        } else {
-            dir = 0;
-        }
-        if (dir) {
-            Luadirentry ldir(dir);
-            ldir.pushdestruct(L);
-        } else {
-            L->push();
-        }
-        r = 1;
-        free(datas);
-        break;
-    case CDUTILS_FINDDIRENTRY:
-        adir = (cdutils::DirEntry *) LuaObject::getme(L, 2);
-        path = L->tostring(3);
-        bdir = cd->find_dir_entry(&datas, adir, path);
-        if ((bdir) && bdir->R) {
-            dir = (cdutils::DirEntry *) malloc(bdir->R);
-            memcpy(dir, bdir, bdir->R);
-        } else {
-            dir = 0;
-        }
-        if (dir) {
-            Luadirentry ldir(dir);
-            ldir.pushdestruct(L);
-        } else {
-            L->push();
-        }
-        r = 1;
-        free(datas);
-        break;
-    case CDUTILS_NEWCDFILE:
-        if (L->istable(2)) {
-            if (n <= 2) {
-                dir = (cdutils::DirEntry *) LuaObject::getme(L, 2);
-                if (n == 2)
-                    mode = L->tonumber(3);
-                cdf = new cdfile(cd, dir, mode);
-            } else {
-                invalid = true;
-            }
-        } else if (L->isnumber(2)) {
-            if (n >= 1) {
-                sector = L->tonumber(2);
-                if (n >= 2)
-                    size = L->tonumber(3);
-                if (n == 3)
-                    mode = L->tonumber(4);
-                cdf = new cdfile(cd, sector, size, mode);
-            } else {
-                invalid = true;
-            }
-        } else {
-            invalid = true;
-        }
-        if (invalid) {
-            L->error("Invalid arguments to constructor of cdfile");
-        } else {
-            Luacdfile luacdf(cdf);
-            luacdf.pushdestruct(L);
-            r = 1;
-        }
-        break;
-    case CDUTILS_UPDATESIZE:
-    case CDUTILS_UPDATESECTOR:
-	path = L->tostring(2);
-	pdir = cd->find_parent(path);
-	dir = cd->find_path(&datas, path);
-	switch (caller) {
-	case CDUTILS_UPDATESIZE:
-	    dir->Size = tolittle((Uint32) L->tonumber(3));
-	    dir->BESize = tobig((Uint32) L->tonumber(3));
-	    break;
-	case CDUTILS_UPDATESECTOR:
-	    dir->Sector = tolittle((Uint32) L->tonumber(3));
-	    dir->BESector = tobig((Uint32) L->tonumber(3));
-	    break;
-	}
-	cd->write_datas(datas, pdir.Size, GUESS, pdir.Sector);
-	free(datas);
-	break;
-    case CDUTILS_CREATESECTOR:
-	mode = L->tonumber(2);
-	sect = L->tonumber(3);
-	if (n == 3)
-	    eof = L->toboolean(4);
-	cd->create_sector(mode, sect, eof);
-	break;
-    }
-
-
-    return r;
-}
-
-int sLua_cdutils::cdutils_proceed_statics(Lua * L, int n, int caller) {
-    int r = 0;
-    Uint32 x;
-    Handle * isor = 0, * isow = 0;
-    Uint32 sector, msf, start = 150;
-    Byte m, s, f;
-
-    switch(caller) {
-    case CDUTILS_NEWCDUTILS:
-        isor = (Handle *) LuaObject::getme(L, 1);
-        if (n == 2)
-            isow = (Handle *) LuaObject::getme(L, 2);
-        {
-            Luacdutils cd(new cdutils(isor, isow));
-            cd.pushdestruct(L);
-        }
-        break;
-    case CDUTILS_SWAPWORD:
-        x = L->tonumber();
-        L->push((lua_Number) cdutils::swap_word(x));
-        r = 1;
-        break;
-    case CDUTILS_SWAPDWORD:
-        x = L->tonumber();
-        L->push((lua_Number) cdutils::swap_dword(x));
-        r = 1;
-        break;
-    case CDUTILS_FROM_BCD:
-        x = L->tonumber();
-        L->push((lua_Number) cdutils::from_BCD(x));
-        r = 1;
-        break;
-    case CDUTILS_TO_BCD:
-        x = L->tonumber();
-        L->push((lua_Number) cdutils::to_BCD(x));
-        r = 1;
-        break;
-    case CDUTILS_IS_VALID_BCD:
-        x = L->tonumber();
-        L->push(cdutils::is_valid_BCD(x));
-        r = 1;
-        break;
-    case CDUTILS_FROM_MSF:
-        if (n <= 2) {
-            msf = L->tonumber(1);
-            if (n == 2)
-                start = L->tonumber(2);
-            L->push((lua_Number) cdutils::from_MSF(msf, start));
-        } else {
-            m = L->tonumber(1);
-            s = L->tonumber(2);
-            f = L->tonumber(3);
-            if (n == 4)
-                start = L->tonumber(4);
-            L->push((lua_Number) cdutils::from_MSF(m, s, f, start));
-        }
-        r = 1;
-        break;
-    case CDUTILS_TO_MSF:
-	sector = L->tonumber(1);
-	if (n == 2)
-	    start = L->tonumber(2);
-	cdutils::to_MSF(sector, m, s, f, start);
-	msf = cdutils::to_MSF(sector, start);
-	L->push((lua_Number) msf);
-	L->push((lua_Number) m);
-	L->push((lua_Number) s);
-	L->push((lua_Number) f);
-	r = 4;
-	break;
-    }
-
-    return r;
-}
-
-
- /***************************\
-|**  class direntry exports **|
- \***************************/
-
-typedef cdutils::DirEntry direntry;
-
-Luadirentry::Luadirentry(cdutils::DirEntry * _dir) : dir(_dir) { }
-
-enum direntry_methods_t {
-    DIRENTRY_INDEX = 0,
-    DIRENTRY_ISHIDDEN,
-    DIRENTRY_ISDIR,
-    DIRENTRY_HASXA,
-    DIRENTRY_ISXADIR,
-    DIRENTRY_ISXAAUDIO,
-    DIRENTRY_ISXASTR,
-    DIRENTRY_ISXAXA,
-    DIRENTRY_ISXAFORM1,
-};
-
-struct lua_functypes_t direntry_methods[] = {
-    { DIRENTRY_INDEX,     "index",     1, 1, {LUA_STRING} },
-    { DIRENTRY_ISHIDDEN,  "ishidden",  0, 0, 0 },
-    { DIRENTRY_ISDIR,     "isdir",     0, 0, 0 },
-    { DIRENTRY_HASXA,     "hasxa",     0, 0, 0 },
-    { DIRENTRY_ISXADIR,   "isxadir",   0, 0, 0 },
-    { DIRENTRY_ISXAAUDIO, "isxaaudio", 0, 0, 0 },
-    { DIRENTRY_ISXASTR,   "isxastr",   0, 0, 0 },
-    { DIRENTRY_ISXAXA,    "isxaxa",    0, 0, 0 },
-    { DIRENTRY_ISXAFORM1, "isxaform1", 0, 0, 0 },
-    { -1, 0, 0, 0, 0 }
-};
-
-class sLua_direntry : public Base {
-  public:
-    DECLARE_METHOD(direntry, DIRENTRY_INDEX);
-    DECLARE_METHOD(direntry, DIRENTRY_ISHIDDEN);
-    DECLARE_METHOD(direntry, DIRENTRY_ISDIR);
-    DECLARE_METHOD(direntry, DIRENTRY_HASXA);
-    DECLARE_METHOD(direntry, DIRENTRY_ISXADIR);
-    DECLARE_METHOD(direntry, DIRENTRY_ISXAAUDIO);
-    DECLARE_METHOD(direntry, DIRENTRY_ISXASTR);
-    DECLARE_METHOD(direntry, DIRENTRY_ISXAXA);
-    DECLARE_METHOD(direntry, DIRENTRY_ISXAFORM1);
-  private:
-    static int direntry_proceed(Lua * L, int n, direntry * obj, int caller);
-};
-
-void Luadirentry::pushmembers(Lua * L) {
-    pushme(L, dir, false);
-
-    PUSH_METAMETHOD(direntry, DIRENTRY_INDEX);
-    PUSH_METHOD(direntry, DIRENTRY_ISHIDDEN);
-    PUSH_METHOD(direntry, DIRENTRY_ISDIR);
-    PUSH_METHOD(direntry, DIRENTRY_HASXA);
-    PUSH_METHOD(direntry, DIRENTRY_ISXADIR);
-    PUSH_METHOD(direntry, DIRENTRY_ISXAAUDIO);
-    PUSH_METHOD(direntry, DIRENTRY_ISXASTR);
-    PUSH_METHOD(direntry, DIRENTRY_ISXAXA);
-    PUSH_METHOD(direntry, DIRENTRY_ISXAFORM1);
-}
-
-int sLua_direntry::direntry_proceed(Lua * L, int n, direntry * dir, int caller) {
-    int r = 0, s, pad;
-    String index;
-    bool has_xa = false;
-    Byte * p;
-
-    s = 33 + dir->N;
-    if (s & 1) {
-        s++;
-        pad = 1;
-    } else {
-        pad = 0;
-    }
-    if (s != dir->R) {
-        if ((s + 14) == dir->R) {
-            p = (Byte *) dir->id + dir->N + pad;
-            if ((p[6] == 'X') && (p[7] == 'A')) {
-                has_xa = true;
-            }
-        }
-    }
-
-    switch (caller) {
-    case DIRENTRY_HASXA:
-        L->push(has_xa);
-        r = 1;
-        break;
-    case DIRENTRY_ISHIDDEN:
-        L->push(dir->Flags & 1 ? true : false);
-        r = 1;
-        break;
-    case DIRENTRY_ISDIR:
-        L->push(dir->Flags & 2 ? true : false);
-        r = 1;
-        break;
-    case DIRENTRY_ISXADIR:
-        L->push(p[4] & 0x80 ? true : false);
-        r = 1;
-        break;
-    case DIRENTRY_ISXAAUDIO:
-        L->push(p[4] & 0x40 ? true : false);
-        r = 1;
-        break;
-    case DIRENTRY_ISXASTR:
-        L->push(p[4] & 0x20 ? true : false);
-        r = 1;
-        break;
-    case DIRENTRY_ISXAXA:
-        L->push(p[4] & 0x10 ? true : false);
-        r = 1;
-        break;
-    case DIRENTRY_ISXAFORM1:
-        L->push(p[4] & 0x08 ? true : false);
-        r = 1;
-        break;
-    case DIRENTRY_INDEX:
-        index = L->tostring();
-        r = 1;
-        if (index == "R") {
-            L->push((lua_Number) dir->R);
-        } else if (index == "NExt") {
-            L->push((lua_Number) dir->NExt);
-        } else if (index == "Sector") {
-            L->push((lua_Number) dir->Sector);
-        } else if (index == "Size") {
-            L->push((lua_Number) dir->Size);
-        } else if (index == "Year") {
-            L->push((lua_Number) dir->Year);
-        } else if (index == "Month") {
-            L->push((lua_Number) dir->Month);
-        } else if (index == "Day") {
-            L->push((lua_Number) dir->Day);
-        } else if (index == "Hour") {
-            L->push((lua_Number) dir->Hour);
-        } else if (index == "Minute") {
-            L->push((lua_Number) dir->Minute);
-        } else if (index == "Second") {
-            L->push((lua_Number) dir->Second);
-        } else if (index == "Offset") {
-            L->push((lua_Number) dir->Offset);
-        } else if (index == "Flags") {
-            L->push((lua_Number) dir->Flags);
-        } else if (index == "HandleUnit") {
-            L->push((lua_Number) dir->HandleUnit);
-        } else if (index == "HandleGap") {
-            L->push((lua_Number) dir->HandleGap);
-        } else if (index == "VolSeq") {
-            L->push((lua_Number) dir->VolSeq);
-        } else if (index == "N") {
-            L->push((lua_Number) dir->N);
-        } else if (index == "id") {
-            char pbuf[256];
-            memcpy(pbuf, dir->id, dir->N);
-            pbuf[dir->N] = 0;
-            L->push(pbuf, dir->N);
-        } else {
-            L->push();
-        }
-    }
-
-    return r;
-}
-
-
- /***************************\
-|**  class direntry exports **|
- \***************************/
-
-typedef isobuilder::Date cddate;
-
-Luacddate::Luacddate(isobuilder::Date * _date) : date(_date) { }
-
-enum cddate_methods_t {
-    CDDATE_INDEX = 0,
-    CDDATE_NEWINDEX,
-};
-
-enum cddate_functions_t {
-    CDDATE_NEWCDDATE = 0,
-};
-
-struct lua_functypes_t cddate_methods[] = {
-    { CDDATE_INDEX,    "index",    1, 1, {LUA_STRING} },
-    { CDDATE_NEWINDEX, "newindex", 2, 2, {LUA_STRING, LUA_NUMBER} },
-    { -1, 0, 0, 0, 0 }
-};
-
-struct lua_functypes_t cddate_functions[] = {
-    { CDDATE_NEWCDDATE, "cddate", 0, 0, 0 },
-    { -1, 0, 0, 0, 0 }
-};
-
-class sLua_cddate : public Base {
-  public:
-    DECLARE_METHOD(cddate, CDDATE_INDEX);
-    DECLARE_METHOD(cddate, CDDATE_NEWINDEX);
-    DECLARE_FUNCTION(cddate, CDDATE_NEWCDDATE);
-  private:
-    static int cddate_proceed(Lua * L, int n, cddate * obj, int caller);
-    static int cddate_proceed_statics(Lua * L, int n, int caller);
-};
-
-void Luacddate::pushmembers(Lua * L) {
-    pushme(L, date, false);
-
-    PUSH_METAMETHOD(cddate, CDDATE_INDEX);
-    PUSH_METAMETHOD(cddate, CDDATE_NEWINDEX);
-}
-
-void Luacddate::pushstatics(Lua * L) throw (GeneralException) {
-    CHECK_METHODS(cddate);
-    CHECK_FUNCTIONS(cddate);
-
-    PUSH_FUNCTION(cddate, CDDATE_NEWCDDATE);
-}
-
-int sLua_cddate::cddate_proceed(Lua * L, int n, cddate * date, int caller) {
-    int r, value;
-    String key;
-
-    switch (caller) {
-    case CDDATE_INDEX:
-        key = L->tostring(2);
-        r = 1;
-        if        (key == "year") {
-            L->push((lua_Number) date->year);
-        } else if (key == "month") {
-            L->push((lua_Number) date->month);
-        } else if (key == "day") {
-            L->push((lua_Number) date->day);
-        } else if (key == "hour") {
-            L->push((lua_Number) date->hour);
-        } else if (key == "minute") {
-            L->push((lua_Number) date->minute);
-        } else if (key == "second") {
-            L->push((lua_Number) date->second);
-        } else if (key == "hundredths") {
-            L->push((lua_Number) date->hundredths);
-        } else if (key == "offset") {
-            L->push((lua_Number) date->offset);
-        } else {
-            L->error("Key " + key + " not in class Date");
-        }
-        break;
-    case CDDATE_NEWINDEX:
-        key = L->tostring(2);
-        value = L->tonumber(3);
-        if (key == "year") {
-            date->year = value;
-        } else if (key == "month") {
-            date->month = value;
-        } else if (key == "day") {
-            date->day = value;
-        } else if (key == "hour") {
-            date->hour = value;
-        } else if (key == "minute") {
-            date->minute = value;
-        } else if (key == "second") {
-            date->second = value;
-        } else if (key == "hundredths") {
-            date->hundredths = value;
-        } else if (key == "offset") {
-            date->offset = value;
-        } else {
-            L->error("Key " + key + " not in class Date");
-        }
-        break;
-    }
-
-    return r;
-}
-
-int sLua_cddate::cddate_proceed_statics(Lua * L, int n, int caller) {
-    int r = 0;
-
-    switch (caller) {
-    case CDDATE_NEWCDDATE:
-        {
-            Luacddate t(new cddate());
-            t.pushdestruct(L);
-        }
-    }
-
-    return r;
-}
-
- /**********************\
-|**  class PVD exports **|
- \**********************/
-
-typedef isobuilder::PVD PVD;
-
-LuaPVD::LuaPVD(struct isobuilder::PVD * _pvd) : pvd(_pvd) { }
-
-enum PVD_methods_t {
-    PVD_INDEX = 0,
-    PVD_NEWINDEX,
-};
-
-enum PVD_functions_t {
-    PVD_NEWPVD = 0,
-};
-
-struct lua_functypes_t PVD_methods[] = {
-    { PVD_INDEX,    "index",    1, 1, {LUA_ANY} },
-    { PVD_NEWINDEX, "newindex", 2, 2, {LUA_ANY, LUA_ANY} },
-    { -1, 0, 0, 0, 0 }
-};
-
-struct lua_functypes_t PVD_functions[] = {
-    { PVD_NEWPVD,   "PVD",      0, 0, 0 },
-    { -1, 0, 0, 0, 0 }
-};
-
-class sLua_PVD : public Base {
-  public:
-    DECLARE_METHOD(PVD, PVD_INDEX);
-    DECLARE_METHOD(PVD, PVD_NEWINDEX);
-
-    DECLARE_FUNCTION(PVD, PVD_NEWPVD);
-
-  private:
-    static int PVD_proceed(Lua * L, int n, PVD * obj, int caller);
-    static int PVD_proceed_statics(Lua * L, int n, int caller);
-};
-
-void LuaPVD::pushmembers(Lua * L) {
-    pushme(L, pvd, false);
-
-    PUSH_METAMETHOD(PVD, PVD_INDEX);
-    PUSH_METAMETHOD(PVD, PVD_NEWINDEX);
-}
-
-void LuaPVD::pushstatics(Lua * L) throw (GeneralException) {
-    CHECK_METHODS(PVD);
-    CHECK_FUNCTIONS(PVD);
-
-    PUSH_FUNCTION(PVD, PVD_NEWPVD);
-}
-
-int sLua_PVD::PVD_proceed(Lua * L, int n, PVD * pvd, int caller) {
-    int r = 0, key_i = 0, value_i;
-    String key_s, value_s;
-    cddate * value_date;
-    bool invalid = false, keyisstring;
-
-    if (L->isnumber(2)) {
-        keyisstring = false;
-        key_i = L->tonumber(2);
-    } else {
-        keyisstring = true;
-        key_s = L->tostring(2);
-    }
-    
-    switch (caller) {
-    case PVD_INDEX:
-        r = 1;
-        if        (keyisstring && (key_s == "sysid")) {
-            L->push(pvd->sysid);
-        } else if (keyisstring && (key_s == "volid")) {
-            L->push(pvd->volid);
-        } else if (keyisstring && (key_s == "volsetid")) {
-            L->push(pvd->volsetid);
-        } else if (keyisstring && (key_s == "pubid")) {
-            L->push(pvd->pubid);
-        } else if (keyisstring && (key_s == "prepid")) {
-            L->push(pvd->prepid);
-        } else if (keyisstring && (key_s == "appid")) {
-            L->push(pvd->appid);
-        } else if (keyisstring && (key_s == "copyright")) {
-            L->push(pvd->copyright);
-        } else if (keyisstring && (key_s == "abstract")) {
-            L->push(pvd->abstract);
-        } else if (keyisstring && (key_s == "biblio")) {
-            L->push(pvd->biblio);
-        } else if (keyisstring && (key_s == "volcreat")) {
-            {
-                Luacddate date(&pvd->volcreat);
-                date.push(L);
-            }
-        } else if (keyisstring && (key_s == "modif")) {
-            {
-                Luacddate date(&pvd->modif);
-                date.push(L);
-            }
-        } else if (keyisstring && (key_s == "volexp")) {
-            {
-                Luacddate date(&pvd->volexp);
-                date.push(L);
-            }
-        } else if (keyisstring && (key_s == "voleff")) {
-            {
-                Luacddate date(&pvd->voleff);
-                date.push(L);
-            }
-        } else if (!keyisstring && (key_i >= 0) && (key_i < 512)) {
-            L->push((lua_Number) pvd->appdata[key_i]);
-        } else {
-            invalid = true;
-        }
-        break;
-    case PVD_NEWINDEX:
-        if        (keyisstring && (key_s == "sysid")) {
-            if (L->isstring(3)) {
-                value_s = L->tostring(3);
-                pvd->sysid = value_s;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "volid")) {
-            if (L->isstring(3)) {
-                value_s = L->tostring(3);
-                pvd->volid = value_s;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "volsetid")) {
-            if (L->isstring(3)) {
-                value_s = L->tostring(3);
-                pvd->volsetid = value_s;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "pubid")) {
-            if (L->isstring(3)) {
-                value_s = L->tostring(3);
-                pvd->pubid = value_s;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "prepid")) {
-            if (L->isstring(3)) {
-                value_s = L->tostring(3);
-                pvd->prepid = value_s;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "appid")) {
-            if (L->isstring(3)) {
-                value_s = L->tostring(3);
-                pvd->appid = value_s;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "copyright")) {
-            if (L->isstring(3)) {
-                value_s = L->tostring(3);
-                pvd->copyright = value_s;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "abstract")) {
-            if (L->isstring(3)) {
-                value_s = L->tostring(3);
-                pvd->abstract = value_s;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "biblio")) {
-            if (L->isstring(3)) {
-                value_s = L->tostring(3);
-                pvd->biblio = value_s;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "volcreat")) {
-            if (L->islightuserdata(3)) {
-                value_date = (cddate *) LuaObject::getme(L, 3);
-                pvd->volcreat = *value_date;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "modif")) {
-            if (L->islightuserdata(3)) {
-                value_date = (cddate *) LuaObject::getme(L, 3);
-                pvd->modif = *value_date;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "volexp")) {
-            if (L->islightuserdata(3)) {
-                value_date = (cddate *) LuaObject::getme(L, 3);
-                pvd->volexp = *value_date;
-            } else {
-                invalid = true;
-            }
-        } else if (keyisstring && (key_s == "voleff")) {
-            if (L->islightuserdata(3)) {
-                value_date = (cddate *) LuaObject::getme(L, 3);
-                pvd->voleff = *value_date;
-            } else {
-                invalid = true;
-            }
-        } else if (!keyisstring && (key_i >= 0) && (key_i < 512)) {
-            if (L->isnumber(3)) {
-                pvd->appdata[key_i] = L->tonumber(3);
-            } else {
-                invalid = true;
-            }
-        } else {
-            invalid = true;
-        }
-        break;
-    }
-
-    if (invalid) {
-        L->error("Invalid usage of structure PVD");
-    }
-
-    return r;
-}
-
-int sLua_PVD::PVD_proceed_statics(Lua * L, int n, int caller) {
-    int r = 0;
-
-    switch (caller) {
-    case PVD_NEWPVD:
-        r = 1;
-        {
-            LuaPVD pvd((PVD *) malloc(sizeof(PVD)));
-            pvd.pushdestruct(L);
-        }
-        break;
-    }
-
-    return r;
-}
-
-
- /**************************\
-|**  class DirTree exports **|
- \**************************/
-
-typedef isobuilder::DirTree DirTree;
-
-LuaDirTree::LuaDirTree(isobuilder::DirTree * _dir) : dir(_dir) { }
-
-enum DirTree_methods_t {
-    DIRTREE_INDEX = 0,
-    DIRTREE_NEWINDEX,
-    DIRTREE_FROMDIR,
-    DIRTREE_SETBASICSXA,
-    DIRTREE_FIND,
-};
-
-enum DirTree_functions_t {
-    DIRTREE_NEWDIRTREE = 0,
-};
-
-struct lua_functypes_t DirTree_methods[] = {
-    { DIRTREE_INDEX,       "index",       1, 1, {LUA_STRING} },
-    { DIRTREE_NEWINDEX,    "newindex",    2, 2, {LUA_STRING, LUA_ANY} },
-    { DIRTREE_FROMDIR,     "fromdir",     1, 1, {LUA_OBJECT} },
-    { DIRTREE_SETBASICSXA, "setbasicsxa", 0, 0, 0 },
-    { DIRTREE_FIND,        "find",        1, 1, {LUA_STRING} },
-    { -1, 0, 0, 0, 0 }
-};
-
-struct lua_functypes_t DirTree_functions[] = {
-    { DIRTREE_NEWDIRTREE, "DirTree", 1, 2, {LUA_OBJECT, LUA_BOOLEAN} },
-    { -1, 0, 0, 0, 0 }
-};
-
-class sLua_DirTree : public Base {
-  public:
-    DECLARE_METHOD(DirTree, DIRTREE_INDEX);
-    DECLARE_METHOD(DirTree, DIRTREE_NEWINDEX);
-    DECLARE_METHOD(DirTree, DIRTREE_FROMDIR);
-    DECLARE_METHOD(DirTree, DIRTREE_SETBASICSXA);
-    DECLARE_METHOD(DirTree, DIRTREE_FIND);
-
-    DECLARE_FUNCTION(DirTree, DIRTREE_NEWDIRTREE);
-  private:
-    static int DirTree_proceed(Lua * L, int n, DirTree * obj, int caller);
-    static int DirTree_proceed_statics(Lua * L, int n, int caller);
-};
-
-void LuaDirTree::pushmembers(Lua * L) {
-    pushme(L, dir);
-
-    PUSH_METAMETHOD(DirTree, DIRTREE_INDEX);
-    PUSH_METAMETHOD(DirTree, DIRTREE_NEWINDEX);
-
-    PUSH_METHOD(DirTree, DIRTREE_FROMDIR);
-    PUSH_METHOD(DirTree, DIRTREE_SETBASICSXA);
-    PUSH_METHOD(DirTree, DIRTREE_FIND);
-}
-
-void LuaDirTree::pushstatics(Lua * L) throw (GeneralException) {
-    CHECK_METHODS(DirTree);
-    CHECK_FUNCTIONS(DirTree);
-
-    PUSH_FUNCTION(DirTree, DIRTREE_NEWDIRTREE);
-}
-
-int sLua_DirTree::DirTree_proceed(Lua * L, int n, DirTree * dir, int caller) {
-    int r = 0, value_i;
-    direntry * dirent;
-    DirTree * rdir;
-    String f, key, value_s;
-    bool invalid = false, value_b;
-    cddate * value_date;
-
-    switch (caller) {
-    case DIRTREE_FROMDIR:
-        dirent = (direntry *) LuaObject::getme(L, 2);
-        dir->fromdir(dirent);
-        break;
-    case DIRTREE_SETBASICSXA:
-        dir->setbasicsxa();
-        break;
-    case DIRTREE_FIND:
-        f = L->tostring(2);
-        rdir = dir->Find(f);
-        if (rdir) {
-            LuaDirTree dirt(rdir);
-            dirt.push(L);
-        } else {
-            L->push();
-        }
-        break;
-    case DIRTREE_INDEX:
-        key = L->tostring(2);
-        r = 1;
-        if        (key == "sector") {
-            L->push((lua_Number) dir->sector);
-        } else if (key == "size") {
-            L->push((lua_Number) dir->size);
-        } else if (key == "hidden") {
-            L->push(dir->hidden);
-        } else if (key == "hardhide") {
-            L->push(dir->hardhide);
-        } else if (key == "name") {
-            L->push(dir->name);
-        } else if (key == "creation") {
-            Luacddate date(&dir->creation);
-            date.push(L);
-        } else if (key == "have_xa") {
-            L->push(dir->have_xa);
-        } else if (key == "xa_dir") {
-            L->push(dir->xa_dir);
-        } else if (key == "xa_audio") {
-            L->push(dir->xa_audio);
-        } else if (key == "xa_str") {
-            L->push(dir->xa_str);
-        } else if (key == "xa_xa") {
-            L->push(dir->xa_xa);
-        } else if (key == "xa_form1") {
-            L->push(dir->xa_form1);
-        } else if (key == "mode") {
-            L->push((lua_Number) dir->mode);
-        } else if (key == "father") {
-            LuaDirTree tdir(dir->Father());
-            tdir.push(L);
-        } else if (key == "child") {
-            LuaDirTree tdir(dir->Child());
-            tdir.push(L);
-        } else if (key == "brother") {
-            LuaDirTree tdir(dir->Brother());
-            tdir.push(L);
-        } else if (key == "isdir") {
-            L->push(dir->isdir());
-        } else {
-            invalid = true;
-        }
-        break;
-    case DIRTREE_NEWINDEX:
-        key = L->tostring(2);
-        if        (key == "sector") {
-            if (L->isnumber(3)) {
-                value_i = L->tonumber(3);
-                dir->sector = value_i;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "size") {
-            if (L->isnumber(3)) {
-                value_i = L->tonumber(3);
-                dir->size = value_i;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "hidden") {
-            if (L->isboolean(3)) {
-                value_b = L->toboolean(3);
-                dir->hidden = value_b;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "hardhide") {
-            if (L->isboolean(3)) {
-                value_b = L->toboolean(3);
-                dir->hardhide = value_b;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "name") {
-            if (L->isstring(3)) {
-                value_s = L->tostring(3);
-                dir->name = value_s;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "creation") {
-            if (L->islightuserdata(3)) {
-                value_date = (cddate *) LuaObject::getme(L, 3);
-                dir->creation = *value_date;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "have_xa") {
-            if (L->isboolean(3)) {
-                value_b = L->toboolean(3);
-                dir->have_xa = value_b;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "xa_dir") {
-            if (L->isboolean(3)) {
-                value_b = L->toboolean(3);
-                dir->xa_dir = value_b;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "xa_audio") {
-            if (L->isboolean(3)) {
-                value_b = L->toboolean(3);
-                dir->xa_audio = value_b;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "xa_str") {
-            if (L->isboolean(3)) {
-                value_b = L->toboolean(3);
-                dir->xa_str = value_b;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "xa_xa") {
-            if (L->isboolean(3)) {
-                value_b = L->toboolean(3);
-                dir->xa_xa = value_b;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "xa_form1") {
-            if (L->isboolean(3)) {
-                value_b = L->toboolean(3);
-                dir->xa_form1 = value_b;
-            } else {
-                invalid = true;
-            }
-        } else if (key == "mode") {
-            if (L->isnumber(3)) {
-                value_i = L->tonumber(3);
-                dir->mode = value_i;
-            } else {
-                invalid = true;
-            }
-        } else {
-            invalid = true;
-        }
-        break;
-    }
-
-    if (invalid) {
-        L->error("Invalid usage of structure DirTree");
-    }
-
-    return r;
-}
-
-int sLua_DirTree::DirTree_proceed_statics(Lua * L, int n, int caller) {
-    int r;
-    DirTree * father;
-    bool dir = true;
-
-    switch (caller) {
-    case DIRTREE_NEWDIRTREE:
-        father = (DirTree *) LuaObject::getme(L, 1);
-        if (n == 2)
-            dir = L->toboolean(2);
-        {
-            LuaDirTree dirt(new DirTree(father, dir));
-            dirt.pushdestruct(L);
-        }
-        break;
-    }
-
-    return r;
-}
-
-
- /*****************************\
-|**  class isobuilder exports **|
- \*****************************/
-
-Luaisobuilder::Luaisobuilder(isobuilder * _iso) : iso(_iso) { }
-
-enum isobuilder_methods_t {
-    ISOBUILDER_FOREWORD = 0,
-    ISOBUILDER_FOREWORD_HANDLE,
-    ISOBUILDER_FOREWORD_ARRAY,
-    ISOBUILDER_GETDISPSECT,
-    ISOBUILDER_PUTFILE,
-    ISOBUILDER_PUTDATAS,
-    ISOBUILDER_CREATESECTOR,
-    ISOBUILDER_SETEOF,
-    ISOBUILDER_CLEAREOF,
-    ISOBUILDER_SETBASICS,
-    ISOBUILDER_CREATEDIR,
-    ISOBUILDER_CREATEFILE,
-    ISOBUILDER_COPYDIR,
-    ISOBUILDER_CLOSE,
-};
-
-enum isobuilder_functions_t {
-    ISOBUILDER_NEWISOBUILDER = 0,
-    ISOBUILDER_CREATEPVD_HANDLE,
-    ISOBUILDER_CREATEPVD,
-    ISOBUILDER_CREATEPVD_ARRAY,
-};
-
-struct lua_functypes_t isobuilder_methods[] = {
-    { ISOBUILDER_FOREWORD,          "foreword",          1, 1, {LUA_OBJECT} },
-    { ISOBUILDER_FOREWORD_HANDLE,   "foreword_handle",   1, 2, {LUA_OBJECT, LUA_NUMBER} },
-    { ISOBUILDER_FOREWORD_ARRAY,    "foreword_array",    1, 2, {LUA_TABLE, LUA_NUMBER} },
-    { ISOBUILDER_GETDISPSECT,       "getdispsect",       0, 0, 0},
-    { ISOBUILDER_PUTFILE,           "putfile",           1, 3, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER} },
-    { ISOBUILDER_PUTDATAS,          "putdatas",          2, 4, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
-    { ISOBUILDER_CREATESECTOR,      "createsector",      1, 3, {LUA_TABLE, LUA_NUMBER, LUA_NUMBER} },
-    { ISOBUILDER_SETEOF,            "setEOF",            0, 0, 0 },
-    { ISOBUILDER_CLEAREOF,          "clearEOF",          0, 0, 0 },
-    { ISOBUILDER_SETBASICS,         "setbasics",         1, 5, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER} },
-    { ISOBUILDER_CREATEDIR,         "createdir",         2, 5, {LUA_OBJECT, LUA_STRING, LUA_NUMBER, LUA_OBJECT, LUA_NUMBER} },
-    { ISOBUILDER_CREATEFILE,        "createfile",        3, 5, {LUA_OBJECT, LUA_STRING, LUA_OBJECT, LUA_OBJECT, LUA_NUMBER} },
-    { ISOBUILDER_COPYDIR,           "copydir",           3, 4, {LUA_OBJECT, LUA_OBJECT, LUA_OBJECT, LUA_NUMBER} },
-    { ISOBUILDER_CLOSE,             "close",             0, 3, {LUA_OBJECT, LUA_NUMBER, LUA_NUMBER} },
-    { -1, 0, 0, 0, 0 }
-};
-
-struct lua_functypes_t isobuilder_functions[] = {
-    { ISOBUILDER_NEWISOBUILDER,     "isobuilder",        1, 2, {LUA_OBJECT, LUA_NUMBER} },
-    { ISOBUILDER_CREATEPVD_HANDLE,  "createpvd_handle",  1, 1, {LUA_OBJECT} },
-    { ISOBUILDER_CREATEPVD,         "createpvd",         1, 1, {LUA_OBJECT} },
-    { ISOBUILDER_CREATEPVD_ARRAY,   "createpvd_array",   1, 1, {LUA_TABLE} },
-    { -1, 0, 0, 0, 0 }
-};
-
-class sLua_isobuilder : public Base {
-  public:
-    DECLARE_METHOD(isobuilder, ISOBUILDER_FOREWORD);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_FOREWORD_HANDLE);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_FOREWORD_ARRAY);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_GETDISPSECT);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_PUTFILE);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_PUTDATAS);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_CREATESECTOR);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_SETEOF);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_CLEAREOF);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_SETBASICS);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_CREATEDIR);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_CREATEFILE);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_COPYDIR);
-    DECLARE_METHOD(isobuilder, ISOBUILDER_CLOSE);
-
-    DECLARE_FUNCTION(isobuilder, ISOBUILDER_NEWISOBUILDER);
-    DECLARE_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_HANDLE);
-    DECLARE_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD);
-    DECLARE_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_ARRAY);
-
-  private:
-    static int isobuilder_proceed(Lua * L, int n, isobuilder * obj, int caller);
-    static int isobuilder_proceed_statics(Lua * L, int n, int caller);
-};
-
-void Luaisobuilder::pushmembers(Lua * L) {
-    pushme(L, iso);
-
-    PUSH_METHOD(isobuilder, ISOBUILDER_FOREWORD);
-    PUSH_METHOD(isobuilder, ISOBUILDER_FOREWORD_HANDLE);
-    PUSH_METHOD(isobuilder, ISOBUILDER_FOREWORD_ARRAY);
-    PUSH_METHOD(isobuilder, ISOBUILDER_GETDISPSECT);
-    PUSH_METHOD(isobuilder, ISOBUILDER_PUTFILE);
-    PUSH_METHOD(isobuilder, ISOBUILDER_PUTDATAS);
-    PUSH_METHOD(isobuilder, ISOBUILDER_CREATESECTOR);
-    PUSH_METHOD(isobuilder, ISOBUILDER_SETEOF);
-    PUSH_METHOD(isobuilder, ISOBUILDER_CLEAREOF);
-    PUSH_METHOD(isobuilder, ISOBUILDER_SETBASICS);
-    PUSH_METHOD(isobuilder, ISOBUILDER_CREATEDIR);
-    PUSH_METHOD(isobuilder, ISOBUILDER_CREATEFILE);
-    PUSH_METHOD(isobuilder, ISOBUILDER_COPYDIR);
-    PUSH_METHOD(isobuilder, ISOBUILDER_CLOSE);
-}
-
-void Luaisobuilder::pushstatics(Lua * L) throw (GeneralException) {
-    CHECK_METHODS(isobuilder);
-    CHECK_FUNCTIONS(isobuilder);
-
-    PUSH_FUNCTION(isobuilder, ISOBUILDER_NEWISOBUILDER);
-    PUSH_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_HANDLE);
-    PUSH_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD);
-    PUSH_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_ARRAY);
-}
-
-int sLua_isobuilder::isobuilder_proceed(Lua * L, int n, isobuilder * iso, int caller) {
-    int r = 0, i;
-    Handle * h = 0;
-    int mode = -1, sector = -1, rootsize = 1, ptsize = 1, nvd = 1, rootsect = -1, nsects = -1;
-    size_t size;
-    Byte datas[2352 * 16], * p;
-    PVD * pvd;
-    DirTree * dirt, * rdir;
-    direntry * dire = 0;
-    String name;
-    cdutils * cd;
-
-    switch (caller) {
-    case ISOBUILDER_FOREWORD:
-        cd = (cdutils *) LuaObject::getme(L, 2);
-        iso->foreword(cd);
-        break;
-    case ISOBUILDER_FOREWORD_HANDLE:
-        mode = MODE_RAW;
-        h = (Handle *) LuaObject::getme(L, 2);
-        if (n == 2)
-            mode = L->tonumber(3);
-        iso->foreword(h, mode);
-        break;
-    case ISOBUILDER_FOREWORD_ARRAY:
-        mode = MODE_RAW;
-        if (n == 2)
-            mode = L->tonumber(3);
-        for (i = 0; i < 16 * 2352; i++) {
-            L->push((lua_Number) i);
-            L->gettable(2);
-            datas[i] = L->tonumber();
-            L->pop();
-        }
-        iso->foreword(datas, mode);
-        break;
-    case ISOBUILDER_GETDISPSECT:
-        L->push((lua_Number) iso->getdispsect());
-        r = 1;
-        break;
-    case ISOBUILDER_PUTFILE:
-        h = (Handle *) LuaObject::getme(L, 2);
-        if (n >= 2)
-            mode = L->tonumber(3);
-        if (n >= 3)
-            sector = L->tonumber(4);
-        L->push((lua_Number) iso->putfile(h, mode, sector));
-        r = 1;
-        break;
-    case ISOBUILDER_PUTDATAS:
-        size = L->tonumber(3);
-        if (n >= 3)
-            mode = L->tonumber(4);
-        if (n >= 4)
-            sector = L->tonumber(5);
-        p = (Byte *) malloc(size);
-        for (i = 0; i < size; i++) {
-            L->push((lua_Number) i);
-            L->gettable(2);
-            p[i] = L->tonumber();
-            L->pop();
-        }
-        L->push((lua_Number) iso->putdatas(p, size, mode, sector));
-        r = 1;
-        free(p);
-        break;
-    case ISOBUILDER_CREATESECTOR:
-        if (n >= 2)
-            mode = L->tonumber(3);
-        if (n >= 3)
-            sector = L->tonumber(4);
-        for (i = 0; i < 2352; i++) {
-            L->push((lua_Number) i);
-            L->gettable(2);
-            datas[i] = L->tonumber();
-            L->pop();
-        }
-        L->push((lua_Number) iso->createsector(datas, mode, sector));
-        r = 1;
-        break;
-    case ISOBUILDER_SETEOF:
-        iso->setEOF();
-        break;
-    case ISOBUILDER_CLEAREOF:
-        iso->clearEOF();
-        break;
-    case ISOBUILDER_SETBASICS:
-        pvd = (PVD *) LuaObject::getme(L, 2);
-        if (n >= 2)
-            rootsize = L->tonumber(3);
-        if (n >= 3)
-            ptsize = L->tonumber(4);
-        if (n >= 4)
-            nvd = L->tonumber(5);
-        if (n >= 5)
-            rootsect = L->tonumber(6);
-        rdir = iso->setbasics(*pvd, rootsize, ptsize, nvd, rootsect);
-        {
-            LuaDirTree t(rdir);
-            t.push(L);
-        }
-        r = 1;
-        break;
-    case ISOBUILDER_CREATEDIR:
-        size = 1;
-        dirt = 0;
-        dirt = (DirTree *) LuaObject::getme(L, 2);
-        name = L->tostring(3);
-        if (n >= 3)
-            size = L->tonumber(4);
-        if (n >= 4)
-            dire = (direntry *) LuaObject::getme(L, 5);
-        if (n >= 5)
-            mode = L->tonumber(6);
-        rdir = iso->createdir(dirt, name, size, dire, mode);
-        {
-            LuaDirTree t(rdir);
-            t.push(L);
-        }
-        r = 1;
-        break;
-    case ISOBUILDER_CREATEFILE:
-        dirt = (DirTree *) LuaObject::getme(L, 2);
-        name = L->tostring(3);
-        h = (Handle *) LuaObject::getme(L, 4);
-        if (n >= 4)
-            dire = (direntry *) LuaObject::getme(L, 5);
-        if (n >= 5)
-            mode = L->tonumber(6);
-        rdir = iso->createfile(dirt, h, name, dire, mode);
-        {
-            LuaDirTree t(rdir);
-            t.push(L);
-        }
-        r = 1;
-        break;
-    case ISOBUILDER_COPYDIR:
-        dirt = (DirTree *) LuaObject::getme(L, 2);
-        cd = (cdutils *) LuaObject::getme(L, 3);
-        dire = (direntry *) LuaObject::getme(L, 4);
-        if (n >= 4)
-            mode = L->tonumber(5);
-        iso->copydir(dirt, cd, dire, mode);
-        break;
-    case ISOBUILDER_CLOSE:
-        if (n >= 1)
-            h = (Handle *) LuaObject::getme(L, 2);
-        if (n >= 2)
-            mode = L->tonumber(3);
-	if (n >= 3)
-	    nsects = L->tonumber(4);
-        iso->close(h, mode, nsects);
-        break;
-    }
-
-    return r;
-}
-
-int sLua_isobuilder::isobuilder_proceed_statics(Lua * L, int n, int caller) {
-    int r = 0, i;
-    Handle * h;
-    int mode = MODE2_FORM1;
-    cdutils * cd;
-    Byte datas[2048];
-    PVD * pvd;
-
-    switch (caller) {
-    case ISOBUILDER_NEWISOBUILDER:
-        h = (Handle *) LuaObject::getme(L, 1);
-        if (n >= 2)
-            mode = L->tonumber();
-        {
-            Luaisobuilder t(new isobuilder(h, mode));
-            t.pushdestruct(L);
-        }
-        r = 1;
-        break;
-    case ISOBUILDER_CREATEPVD_HANDLE:
-        h = (Handle *) LuaObject::getme(L, 1);
-	pvd = (PVD *) malloc(sizeof(PVD));
-	*pvd = isobuilder::createpvd(h);
-        {
-            LuaPVD t(pvd);
-            t.pushdestruct(L);
-        }
-        r = 1;
-        break;
-    case ISOBUILDER_CREATEPVD:
-        cd = (cdutils *) LuaObject::getme(L, 1);
-	pvd = (PVD *) malloc(sizeof(PVD));
-        *pvd = isobuilder::createpvd(cd);
-        {
-            LuaPVD t(pvd);
-            t.pushdestruct(L);
-        }
-        r = 1;
-        break;
-    case ISOBUILDER_CREATEPVD_ARRAY:
-        for (i = 0; i < 2048; i++) {
-            L->push((lua_Number) i);
-            L->gettable(1);
-            datas[i] = L->tonumber();
-            L->pop();
-        }
-	pvd = (PVD *) malloc(sizeof(PVD));
-	*pvd = isobuilder::createpvd(datas);
-        {
-            LuaPVD t(pvd);
-            t.pushdestruct(L);
-        }
-        r = 1;
-        break;
-    }
-
-    return r;
-}
+
+void Luaisobuilder::pushmembers(Lua * L) {
+    pushme(L, iso);
+
+    PUSH_METHOD(isobuilder, ISOBUILDER_FOREWORD);
+    PUSH_METHOD(isobuilder, ISOBUILDER_FOREWORD_HANDLE);
+    PUSH_METHOD(isobuilder, ISOBUILDER_FOREWORD_ARRAY);
+    PUSH_METHOD(isobuilder, ISOBUILDER_GETDISPSECT);
+    PUSH_METHOD(isobuilder, ISOBUILDER_PUTFILE);
+    PUSH_METHOD(isobuilder, ISOBUILDER_PUTDATAS);
+    PUSH_METHOD(isobuilder, ISOBUILDER_CREATESECTOR);
+    PUSH_METHOD(isobuilder, ISOBUILDER_SETEOF);
+    PUSH_METHOD(isobuilder, ISOBUILDER_CLEAREOF);
+    PUSH_METHOD(isobuilder, ISOBUILDER_SETBASICS);
+    PUSH_METHOD(isobuilder, ISOBUILDER_CREATEDIR);
+    PUSH_METHOD(isobuilder, ISOBUILDER_CREATEFILE);
+    PUSH_METHOD(isobuilder, ISOBUILDER_COPYDIR);
+    PUSH_METHOD(isobuilder, ISOBUILDER_CLOSE);
+}
+
+void Luaisobuilder::pushstatics(Lua * L) throw (GeneralException) {
+    CHECK_METHODS(isobuilder);
+    CHECK_FUNCTIONS(isobuilder);
+
+    PUSH_FUNCTION(isobuilder, ISOBUILDER_NEWISOBUILDER);
+    PUSH_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_HANDLE);
+    PUSH_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD);
+    PUSH_FUNCTION(isobuilder, ISOBUILDER_CREATEPVD_ARRAY);
+}
+
+int sLua_isobuilder::isobuilder_proceed(Lua * L, int n, isobuilder * iso, int caller) {
+    int r = 0, i;
+    Handle * h = 0;
+    int mode = -1, sector = -1, rootsize = 1, ptsize = 1, nvd = 1, rootsect = -1, nsects = -1;
+    size_t size;
+    Byte datas[2352 * 16], * p;
+    PVD * pvd;
+    DirTree * dirt, * rdir;
+    direntry * dire = 0;
+    String name;
+    cdutils * cd;
+
+    switch (caller) {
+    case ISOBUILDER_FOREWORD:
+        cd = (cdutils *) LuaObject::getme(L, 2);
+        iso->foreword(cd);
+        break;
+    case ISOBUILDER_FOREWORD_HANDLE:
+        mode = MODE_RAW;
+        h = (Handle *) LuaObject::getme(L, 2);
+        if (n == 2)
+            mode = L->tonumber(3);
+        iso->foreword(h, mode);
+        break;
+    case ISOBUILDER_FOREWORD_ARRAY:
+        mode = MODE_RAW;
+        if (n == 2)
+            mode = L->tonumber(3);
+        for (i = 0; i < 16 * 2352; i++) {
+            L->push((lua_Number) i);
+            L->gettable(2);
+            datas[i] = L->tonumber();
+            L->pop();
+        }
+        iso->foreword(datas, mode);
+        break;
+    case ISOBUILDER_GETDISPSECT:
+        L->push((lua_Number) iso->getdispsect());
+        r = 1;
+        break;
+    case ISOBUILDER_PUTFILE:
+        h = (Handle *) LuaObject::getme(L, 2);
+        if (n >= 2)
+            mode = L->tonumber(3);
+        if (n >= 3)
+            sector = L->tonumber(4);
+        L->push((lua_Number) iso->putfile(h, mode, sector));
+        r = 1;
+        break;
+    case ISOBUILDER_PUTDATAS:
+        size = L->tonumber(3);
+        if (n >= 3)
+            mode = L->tonumber(4);
+        if (n >= 4)
+            sector = L->tonumber(5);
+        p = (Byte *) malloc(size);
+        for (i = 0; i < size; i++) {
+            L->push((lua_Number) i);
+            L->gettable(2);
+            p[i] = L->tonumber();
+            L->pop();
+        }
+        L->push((lua_Number) iso->putdatas(p, size, mode, sector));
+        r = 1;
+        free(p);
+        break;
+    case ISOBUILDER_CREATESECTOR:
+        if (n >= 2)
+            mode = L->tonumber(3);
+        if (n >= 3)
+            sector = L->tonumber(4);
+        for (i = 0; i < 2352; i++) {
+            L->push((lua_Number) i);
+            L->gettable(2);
+            datas[i] = L->tonumber();
+            L->pop();
+        }
+        L->push((lua_Number) iso->createsector(datas, mode, sector));
+        r = 1;
+        break;
+    case ISOBUILDER_SETEOF:
+        iso->setEOF();
+        break;
+    case ISOBUILDER_CLEAREOF:
+        iso->clearEOF();
+        break;
+    case ISOBUILDER_SETBASICS:
+        pvd = (PVD *) LuaObject::getme(L, 2);
+        if (n >= 2)
+            rootsize = L->tonumber(3);
+        if (n >= 3)
+            ptsize = L->tonumber(4);
+        if (n >= 4)
+            nvd = L->tonumber(5);
+        if (n >= 5)
+            rootsect = L->tonumber(6);
+        rdir = iso->setbasics(*pvd, rootsize, ptsize, nvd, rootsect);
+        {
+            LuaDirTree t(rdir);
+            t.push(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_CREATEDIR:
+        size = 1;
+        dirt = 0;
+        dirt = (DirTree *) LuaObject::getme(L, 2);
+        name = L->tostring(3);
+        if (n >= 3)
+            size = L->tonumber(4);
+        if (n >= 4)
+            dire = (direntry *) LuaObject::getme(L, 5);
+        if (n >= 5)
+            mode = L->tonumber(6);
+        rdir = iso->createdir(dirt, name, size, dire, mode);
+        {
+            LuaDirTree t(rdir);
+            t.push(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_CREATEFILE:
+        dirt = (DirTree *) LuaObject::getme(L, 2);
+        name = L->tostring(3);
+        h = (Handle *) LuaObject::getme(L, 4);
+        if (n >= 4)
+            dire = (direntry *) LuaObject::getme(L, 5);
+        if (n >= 5)
+            mode = L->tonumber(6);
+        rdir = iso->createfile(dirt, h, name, dire, mode);
+        {
+            LuaDirTree t(rdir);
+            t.push(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_COPYDIR:
+        dirt = (DirTree *) LuaObject::getme(L, 2);
+        cd = (cdutils *) LuaObject::getme(L, 3);
+        dire = (direntry *) LuaObject::getme(L, 4);
+        if (n >= 4)
+            mode = L->tonumber(5);
+        iso->copydir(dirt, cd, dire, mode);
+        break;
+    case ISOBUILDER_CLOSE:
+        if (n >= 1)
+            h = (Handle *) LuaObject::getme(L, 2);
+        if (n >= 2)
+            mode = L->tonumber(3);
+	if (n >= 3)
+	    nsects = L->tonumber(4);
+        iso->close(h, mode, nsects);
+        break;
+    }
+
+    return r;
+}
+
+int sLua_isobuilder::isobuilder_proceed_statics(Lua * L, int n, int caller) {
+    int r = 0, i;
+    Handle * h;
+    int mode = MODE2_FORM1;
+    cdutils * cd;
+    Byte datas[2048];
+    PVD * pvd;
+
+    switch (caller) {
+    case ISOBUILDER_NEWISOBUILDER:
+        h = (Handle *) LuaObject::getme(L, 1);
+        if (n >= 2)
+            mode = L->tonumber();
+        {
+            Luaisobuilder t(new isobuilder(h, mode));
+            t.pushdestruct(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_CREATEPVD_HANDLE:
+        h = (Handle *) LuaObject::getme(L, 1);
+	pvd = (PVD *) malloc(sizeof(PVD));
+	*pvd = isobuilder::createpvd(h);
+        {
+            LuaPVD t(pvd);
+            t.pushdestruct(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_CREATEPVD:
+        cd = (cdutils *) LuaObject::getme(L, 1);
+	pvd = (PVD *) malloc(sizeof(PVD));
+        *pvd = isobuilder::createpvd(cd);
+        {
+            LuaPVD t(pvd);
+            t.pushdestruct(L);
+        }
+        r = 1;
+        break;
+    case ISOBUILDER_CREATEPVD_ARRAY:
+        for (i = 0; i < 2048; i++) {
+            L->push((lua_Number) i);
+            L->gettable(1);
+            datas[i] = L->tonumber();
+            L->pop();
+        }
+	pvd = (PVD *) malloc(sizeof(PVD));
+	*pvd = isobuilder::createpvd(datas);
+        {
+            LuaPVD t(pvd);
+            t.pushdestruct(L);
+        }
+        r = 1;
+        break;
+    }
+
+    return r;
+}
-- 
cgit v1.2.3