diff options
author | pixel <pixel> | 2004-11-27 21:44:44 +0000 |
---|---|---|
committer | pixel <pixel> | 2004-11-27 21:44:44 +0000 |
commit | d38e80ee04afe582e70150d3884e56c05f3fd7a8 (patch) | |
tree | f2627c50fa22aea89447e8406ac418eb68650d3d /lib/cdutils.cpp | |
parent | 50f0dd331f8168fb5b2cd60c70178fad627b7fb6 (diff) |
Large dos2unix commit...
Diffstat (limited to 'lib/cdutils.cpp')
-rw-r--r-- | lib/cdutils.cpp | 1904 |
1 files changed, 952 insertions, 952 deletions
diff --git a/lib/cdutils.cpp b/lib/cdutils.cpp index 953b76e..ea4ff4c 100644 --- a/lib/cdutils.cpp +++ b/lib/cdutils.cpp @@ -1,952 +1,952 @@ -/*
- * 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.32 2004-10-20 07:15:43 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) {
- try {
- 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);
- } catch (GeneralException e) {
- if (number >= 0)
- printm(M_ERROR, "Trouble reading sector %i: %s\n", number, e.GetMsg());
- else
- printm(M_ERROR, "Trouble reading sector: %s\n", e.GetMsg());
-
- if (type != GUESS)
- memset(buffer, 0, sec_sizes[type]);
- return 0;
- }
- 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;
-}
+/* + * 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.33 2004-11-27 21:47:56 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) { + try { + 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); + } catch (GeneralException e) { + if (number >= 0) + printm(M_ERROR, "Trouble reading sector %i: %s\n", number, e.GetMsg()); + else + printm(M_ERROR, "Trouble reading sector: %s\n", e.GetMsg()); + + if (type != GUESS) + memset(buffer, 0, sec_sizes[type]); + return 0; + } + 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; +} |