summaryrefslogtreecommitdiff
path: root/lib/cdutils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cdutils.cpp')
-rw-r--r--lib/cdutils.cpp234
1 files changed, 223 insertions, 11 deletions
diff --git a/lib/cdutils.cpp b/lib/cdutils.cpp
index 413f95d..b3468e7 100644
--- a/lib/cdutils.cpp
+++ b/lib/cdutils.cpp
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* $Id: cdutils.cpp,v 1.15 2003-11-25 01:55:45 pixel Exp $ */
+/* $Id: cdutils.cpp,v 1.16 2003-12-04 00:57:35 pixel Exp $ */
#include <stdio.h>
#include <string.h>
@@ -31,11 +31,14 @@ 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) : f_iso_r(r), f_iso_w(w), ppf_file(0), pt1(-1), pt2(-1), snum(0), ptl(0), root(0) {}
+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;
+ void * t = rootDir;
+ free(t);
+ rootDir = 0;
}
unsigned char cdutils::from_BCD(unsigned char x) {
@@ -328,12 +331,13 @@ void cdutils::write_file(Handle * file, int type, int number) {
}
void cdutils::show_head_entry(void) {
- printm(M_BARE, "Sector - Size - Date - Time - Flags - Name\n");
+ printm(M_BARE, "Sector Size Date Time Flags Name XA flags\n");
}
int cdutils::show_entry(struct DirEntry * dir) {
- char pbuf[200];
- if (!dir->R) {
+ char pbuf[200], pad;
+ int s;
+ if ((!dir) || (!dir->R)) {
return 1;
}
@@ -346,10 +350,32 @@ int cdutils::show_entry(struct DirEntry * dir) {
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 - %8i - %2i/%02i/%04i - %2i:%02i:%02i%+03.1f - %c%c%c%c%c%c%c%c - %s\n",
+ 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);
@@ -432,9 +458,11 @@ struct cdutils::DirEntry * cdutils::find_dir_entry(Byte ** bufout, struct cdutil
}
if (rdir->R) {
+ free(*bufout);
*bufout = buffer;
} else {
free(buffer);
+ rdir = 0;
}
return rdir;
}
@@ -512,9 +540,10 @@ int cdutils::show_iso_infos() {
}
int cdutils::get_iso_infos() {
- unsigned char buffer[2048];
+ Byte buffer[2048];
char pbuff[130];
short int s, nogood = 0;
+ int rootsec;
read_sector(buffer, GUESS, 16);
@@ -535,7 +564,10 @@ int cdutils::get_iso_infos() {
pt2 = *((short int *) &(buffer[144]));
snum = *((int *) &(buffer[80]));
ptl = *((long int *) &(buffer[132]));
- rootDir = *((struct DirEntry *) &(buffer[156]));
+ rootsec = ((struct DirEntry *) (&buffer[156]))->Sector;
+ read_sector(buffer, GUESS, rootsec);
+ rootDir = (struct DirEntry *) malloc(buffer[0]);
+ memcpy(rootDir, buffer, buffer[0]);
return 1;
}
@@ -615,7 +647,7 @@ struct cdutils::DirEntry cdutils::find_path(String path) {
if (!**pts)
pts++;
- for (dir = rootDir; *pts; pts++) {
+ for (dir = *rootDir; *pts; pts++) {
if (!strlen(*pts))
continue;
dir = find_dir_entry(&dir, *pts);
@@ -639,7 +671,7 @@ struct cdutils::DirEntry cdutils::find_parent(String path) {
}
if (!*newpath) {
free(newpath);
- return rootDir;
+ return *rootDir;
}
pts = split(newpath, '/');
@@ -658,7 +690,7 @@ struct cdutils::DirEntry cdutils::find_parent(String path) {
if (!**pts)
pts++;
- for (dir = rootDir; *pts; pts++) {
+ for (dir = *rootDir; *pts; pts++) {
if (!strlen(*pts))
continue;
dir = find_dir_entry(&dir, *pts);
@@ -671,3 +703,183 @@ struct cdutils::DirEntry cdutils::find_parent(String path) {
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") {
+ if (_size == -1) {
+ size = 0;
+ }
+ if (mode == GUESS) {
+ mode = cd->guess_type(sector);
+ }
+ dir = 0;
+ itell = 0;
+}
+
+cdfile::~cdfile() {
+ void * t = dir;
+ free(t);
+ dir = 0;
+}
+
+ssize_t cdfile::read(void *buf, size_t count) throw (GeneralException) {
+ Byte buffer[2352];
+ size_t startsec, nsec, startbyte, nstartbytes;
+
+ count = MIN(count, (size_t) (size - itell));
+
+ if (!count)
+ 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, mode, startsec + 1, count);
+ }
+
+ 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;
+}