summaryrefslogtreecommitdiff
path: root/cd-tool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cd-tool.cpp')
-rw-r--r--cd-tool.cpp273
1 files changed, 273 insertions, 0 deletions
diff --git a/cd-tool.cpp b/cd-tool.cpp
new file mode 100644
index 0000000..1994561
--- /dev/null
+++ b/cd-tool.cpp
@@ -0,0 +1,273 @@
+/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002 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
+ */
+
+#include <getopt.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include "cdutils.h"
+#include "generic.h"
+#include "fileutils.h"
+
+int lga = 0;
+struct option long_options[] = {
+ {"help", 0, NULL, 'h'},
+ {"ppf", 1, NULL, 'p'},
+ {"mode", 1, NULL, 'm'},
+ {"force", 1, NULL, 'f'},
+ {0, 0, NULL, 0 }
+};
+
+void showhelp(void) {
+ printm(M_BARE,
+"Usage:\n"
+"cd-tool [-m <mode>] [-p <ppf file>] [-f] <isofile> <command> [command args]\n"
+"Where mode can be 1 for MODE 1, 2 for MODE 2, 3 for MODE 2 FORM 1,\n"
+"4 for MODE 2 FORM 2 and 5 for autodetect, which is the default behaviour.\n"
+"\n"
+"Command can be one of:\n"
+" infos - dumps a bunch of infos about the iso.\n"
+" path - dumps the path table.\n"
+" printdir <path> - show the directoy listing of <path>\n"
+" extract-file <file> <path> - extract the file <path> to <file>\n"
+" extract <file> <addr> <size> - extract some sectors to <file>\n"
+" insert-file <file> <path> - insert the file to <path>\n"
+" insert <file> <addr> - insert some sectors at <addr>\n"
+"\n");
+}
+
+int main(int argc, char ** argv) {
+ int type = GUESS, c, size, force = 0, sector;
+ FILE * iso_r, * iso_w;
+ char * ppf = 0, * iso_name = 0, * arg1 = 0, * arg2 = 0, * f;
+
+ verbosity = M_WARNING;
+
+ while ((c = getopt_long(argc, argv, "Hhm:p:f", long_options, NULL)) != EOF) {
+ switch (c) {
+ case 'h':
+ case 'H':
+ case '?':
+ showhelp();
+ exit(0);
+ case 'm':
+ type = atoi(optarg);
+ break;
+ case 'p':
+ ppf = strdup(optarg);
+ break;
+ case 'f':
+ force = 1;
+ break;
+ }
+ }
+
+ if (argc == optind) {
+ showhelp();
+ printm(M_ERROR, "Need an iso filename to work on.\n");
+ exit(-1);
+ }
+
+ iso_name = argv[optind++];
+
+ if (!(iso_r = fopen(iso_name, "r"))) {
+ printm(M_ERROR, "Failed to open %s for reading.\n", iso_name);
+ exit(-1);
+ }
+
+ if (argc == optind) {
+ showhelp();
+ printm(M_ERROR, "Need a command to execute.\n");
+ exit(-1);
+ }
+
+ get_iso_infos(iso_r);
+
+ if (!strcmp(argv[optind], "infos")) {
+ show_iso_infos(iso_r);
+ } else if (!strcmp(argv[optind], "path")) {
+ show_pt_infos(iso_r);
+ } else if (!strcmp(argv[optind], "printdir")) {
+ struct DirEntry dir;
+ optind++;
+ if ((argc - 1) != optind) {
+ showhelp();
+ printm(M_ERROR, "printdir needs one argument.\n");
+ exit(-1);
+ }
+ arg1 = argv[optind];
+ dir = find_path(iso_r, f = strdup(arg1));
+ free(f);
+ if (!dir.R) {
+ printm(M_ERROR, "Path %s was not found on iso.\n", arg1);
+ exit(-1);
+ }
+ if (!(dir.Flags & 2)) {
+ printm(M_ERROR, "Path %s design a file and not a directory.\n", arg1);
+ exit(-1);
+ }
+ show_head_entry();
+ show_dir(iso_r, &dir);
+ } else if (!strcmp(argv[optind], "extract-file")) {
+ struct DirEntry dir;
+ FILE * file;
+
+ optind++;
+ if ((argc - 2) != optind) {
+ showhelp();
+ printm(M_ERROR, "extract-file needs two arguments.\n");
+ exit(-1);
+ }
+ arg1 = argv[optind++];
+ arg2 = argv[optind++];
+ if (!(file = fopen(arg1, "w"))) {
+ printm(M_ERROR, "Failed to open file %s for writing.\n", arg1);
+ exit(-1);
+ }
+ dir = find_path(iso_r, f = strdup(arg2));
+ free(f);
+ if (!dir.R) {
+ printm(M_ERROR, "Path %s was not found on iso.\n", arg2);
+ exit(-1);
+ }
+ printm(M_STATUS, "Reading path %s to file %s.\n", arg2, arg1);
+ read_file(iso_r, file, type, dir.Sector, dir.Size);
+ } else if (!strcmp(argv[optind], "extract")) {
+ FILE * file;
+
+ optind++;
+ if ((argc - 3) != optind) {
+ showhelp();
+ printm(M_ERROR, "extract needs three arguments.\n");
+ exit(-1);
+ }
+ arg1 = argv[optind++];
+ size = atoi(argv[optind++]);
+ sector = atoi(argv[optind++]);
+ if (!(file = fopen(arg1, "w"))) {
+ printm(M_ERROR, "Failed to open file %s for writing.\n", arg1);
+ exit(-1);
+ }
+ printm(M_STATUS, "Reading %i bytes from sector %i to file %s.\n", size, sector, arg1);
+ read_file(iso_r, file, type, sector, size);
+ } else if (!strcmp(argv[optind], "insert-file")) {
+ struct DirEntry dir, * d;
+ unsigned char * buffer;
+ FILE * file;
+ int old_type;
+ if (!(iso_w = fopen(iso_name, "wa"))) {
+ printm(M_ERROR, "Failed to open %s for writing.\n", iso_name);
+ exit(-1);
+ }
+ fseek(iso_w, 0, SEEK_SET);
+
+ if (ppf) {
+ if (open_ppf(ppf, iso_r, "Created by CD-Tool") < 0) {
+ printm(M_ERROR, "Failed to open file %s for writing.\n", ppf);
+ }
+ }
+
+ optind++;
+ if ((argc - 2) != optind) {
+ showhelp();
+ printm(M_ERROR, "insert-file needs two arguments.\n");
+ exit(-1);
+ }
+ arg1 = argv[optind++];
+ arg2 = argv[optind++];
+ if (!(file = fopen(arg1, "r"))) {
+ printm(M_ERROR, "Failed to open file %s for reading.\n", arg1);
+ exit(-1);
+ }
+ dir = find_path(iso_r, f = strdup(arg2));
+ free(f);
+ if (!dir.R) {
+ printm(M_ERROR, "Path %s was not found on iso.\n", arg2);
+ exit(-1);
+ }
+
+ old_type = guess_type(iso_r, dir.Sector);
+
+ if (type == GUESS) {
+ type = old_type;
+ }
+ if (((dir.Size / sec_sizes[old_type]) + ((dir.Size % sec_sizes[old_type]) ? 1 : 0)) <
+ ((filesize(file) / sec_sizes[type]) + ((filesize(file) % sec_sizes[type]) ? 1 : 0))) {
+ if (force) {
+ printm(M_WARNING, "New file too big: %i vs %i in %s.\n", dir.Size, filesize(file), sec_modes[type]);
+ } else {
+ printm(M_ERROR, "New file too big: %i vs %i in %s.\n", dir.Size, filesize(file), sec_modes[type]);
+ exit(-1);
+ }
+ }
+ printm(M_STATUS, "Writing file %s at path %s.\n", arg1, arg2);
+ write_file(iso_r, iso_w, file, type, dir.Sector);
+ printm(M_STATUS, "Updating directory entry.\n");
+ dir = find_parent(iso_r, f = strdup(arg2));
+ free(f);
+ if ((f = strrchr(arg2, '/'))) {
+ f++;
+ } else {
+ f = arg2;
+ }
+ d = find_dir_entry(iso_r, &buffer, &dir, f);
+ d->Size = filesize(file);
+ write_datas(iso_r, iso_w, buffer, GUESS, dir.Sector, dir.Size);
+ free(buffer);
+ } else if (!strcmp(argv[optind], "insert")) {
+ FILE * file;
+ if (!(iso_w = fopen(iso_name, "wa"))) {
+ printm(M_ERROR, "Failed to open %s for writing.\n", iso_name);
+ exit(-1);
+ }
+ fseek(iso_w, 0, SEEK_SET);
+
+ if (ppf) {
+ if (open_ppf(ppf, iso_r, "Created by CD-Tool") < 0) {
+ printm(M_ERROR, "Failed to open file %s for writing.\n", ppf);
+ }
+ }
+
+ optind++;
+ if ((argc - 2) != optind) {
+ showhelp();
+ printm(M_ERROR, "insert needs two arguments.\n");
+ exit(-1);
+ }
+ arg1 = argv[optind++];
+ sector = atoi(argv[optind++]);
+ if (!(file = fopen(arg1, "r"))) {
+ printm(M_ERROR, "Failed to open file %s for reading.\n", arg1);
+ exit(-1);
+ }
+ printm(M_STATUS, "Writing file %s at sector %i.\n", arg1, sector);
+ write_file(iso_r, iso_w, file, type, sector);
+ } else {
+ showhelp();
+ printm(M_ERROR, "Command %s unknow.\n", argv[optind]);
+ exit(-1);
+ }
+
+ exit(0);
+}
+