/* * 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: cd-tool.cpp,v 1.17 2003-12-07 04:44:38 pixel Exp $ */ #include #include #include #include #include #include #include #include "Input.h" #include "Output.h" #include "Buffer.h" #include "BLua.h" #include "cdreader.h" #include "cdutils.h" #include "generic.h" #include "Main.h" #include "cdabstract.h" #include "isobuilder.h" #include "luacd.h" static int myprint(lua_State * L) { const char * t = lua_tostring(L, -1); Base::printm(M_INFO, "From LUA: %s\n", t); return 0; } int lga = 0; struct option long_options[] = { {"help", 0, NULL, 'h'}, {"ppf", 1, NULL, 'p'}, {"mode", 1, NULL, 'm'}, {"force", 0, NULL, 'f'}, {"verbose", 0, NULL, 'v'}, {0, 0, NULL, 0 } }; CODE_BEGINS public: Appli() : cdutil(0), iso_r(0), iso_w(0), file(0) {} virtual ~Appli() { delete cdutil; delete iso_r; delete iso_w; delete file; } private: cdutils * cdutil; Handle * iso_r, * iso_w, * file; void showhelp(void) { printm(M_BARE, "Usage:\n" "%s [-m ] [-p ] [-f] [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, 5 for Raw, and 6 for autodetect, which is the\n" "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 - show the directoy listing of \n" " extract-file - extract the file to \n" " extract - extract some sectors to \n" " insert-file - insert the file to \n" " insert - insert some sectors at \n" " copy - copy to another iso\n" " lua - interpret LUA script\n" "\n", argv[0]); } void probe(void) { std::vector p; if (!cdabstract::canprobe()) { printm(M_ERROR, "Can't probe on this platform.\n"); exit(-1); } p = cdabstract::probe(); printm(M_BARE, "Alvaible devices:\n"); for (std::vector::iterator i = p.begin(); i != p.end(); i++) { printm(M_BARE, *i + "\n"); } } virtual int startup() throw (GeneralException) { int type = GUESS, c, size, force = 0, sector; char * ppf = 0, * iso_name = 0, * arg1 = 0, * arg2 = 0, * f; verbosity = M_WARNING; while ((c = getopt_long(argc, argv, "Hhm:p:fv", long_options, NULL)) != EOF) { switch (c) { case 'h': case 'H': case '?': showhelp(); throw Exit(0); case 'm': type = atoi(optarg); break; case 'p': ppf = strdup(optarg); break; case 'f': force = 1; break; case 'v': verbosity = M_INFO; break; } } if (argc == optind) { showhelp(); printm(M_ERROR, "Need an iso filename to work on.\n"); exit(-1); } iso_name = argv[optind++]; if (!strcmp(iso_name, "probe")) { probe(); exit(-1); } if (argc == optind) { showhelp(); printm(M_ERROR, "Need a command to execute.\n"); exit(-1); } iso_r = cdabstract::open_cd(iso_name); cdutil = new cdutils(iso_r); if (!cdutil->get_iso_infos()) exit(-1); if (!strcmp(argv[optind], "infos")) { cdutil->show_iso_infos(); } else if (!strcmp(argv[optind], "path")) { cdutil->show_pt_infos(); } else if (!strcmp(argv[optind], "printdir")) { cdutils::DirEntry dir; optind++; if ((argc - 1) != optind) { showhelp(); printm(M_ERROR, "printdir needs one argument.\n"); throw Exit(-1); } arg1 = argv[optind]; dir = cdutil->find_path(f = strdup(arg1)); free(f); if (!dir.R) { printm(M_ERROR, "Path %s was not found on iso.\n", arg1); throw Exit(-1); } if (!(dir.Flags & 2)) { printm(M_ERROR, "Path %s is a file and not a directory.\n", arg1); throw Exit(-1); } cdutil->show_head_entry(); cdutil->show_dir(&dir); } else if (!strcmp(argv[optind], "extract-file")) { cdutils::DirEntry * dir; Byte * buffer; optind++; if ((argc - 2) != optind) { showhelp(); printm(M_ERROR, "extract-file needs two arguments.\n"); throw Exit(-1); } arg1 = argv[optind++]; arg2 = argv[optind++]; file = new Output(arg1); dir = cdutil->find_path(&buffer, arg2); if (!dir) { printm(M_ERROR, "Path %s was not found on iso.\n", arg2); throw Exit(-1); } printm(M_STATUS, "Reading path %s to file %s.\n", arg2, arg1); #if 0 cdutil->read_file(file, type, dir->Sector, dir->Size); #else cdfile * f = new cdfile(cdutil, dir, type); printm(M_STATUS, f->GetName()); copy(f, file); delete f; #endif free(buffer); } else if (!strcmp(argv[optind], "extract")) { optind++; if ((argc - 3) != optind) { showhelp(); printm(M_ERROR, "extract needs three arguments.\n"); throw Exit(-1); } arg1 = argv[optind++]; size = atoi(argv[optind++]); sector = atoi(argv[optind++]); file = new Output(arg1); printm(M_STATUS, "Reading %i bytes from sector %i to file %s.\n", size, sector, arg1); cdutil->read_file(file, type, sector, size); } else if (!strcmp(argv[optind], "insert-file")) { cdutils::DirEntry dir, * d; unsigned char * buffer; int old_type; if (ppf) { if (cdutil->open_ppf(ppf, "Created by CD-Tool") < 0) { printm(M_ERROR, "Failed to open file %s for writing.\n", ppf); } } else { iso_w = new Output(iso_name, 0, 0); cdutil->set_iso_w(iso_w); } optind++; if ((argc - 2) != optind) { showhelp(); printm(M_ERROR, "insert-file needs two arguments.\n"); throw Exit(-1); } arg1 = argv[optind++]; arg2 = argv[optind++]; file = new Input(arg1); dir = cdutil->find_path(f = strdup(arg2)); free(f); if (!dir.R) { printm(M_ERROR, "Path %s was not found on iso.\n", arg2); throw Exit(-1); } old_type = cdutil->guess_type(dir.Sector); if (type == GUESS) { type = old_type; } if (((dir.Size / sec_sizes[old_type]) + ((dir.Size % sec_sizes[old_type]) ? 1 : 0)) < (((size_t) file->GetSize() / sec_sizes[type]) + (((size_t) file->GetSize() % sec_sizes[type]) ? 1 : 0))) { if (force) { printm(M_WARNING, "New file too big: %i vs %i in " + sec_modes[type] + ".\n", dir.Size, file->GetSize()); } else { printm(M_ERROR, "New file too big: %i vs %i in " + sec_modes[type] + ".\n", dir.Size, file->GetSize()); throw Exit(-1); } } printm(M_STATUS, "Writing file %s at path %s (sector %i).\n", arg1, arg2, dir.Sector); cdutil->write_file(file, type, dir.Sector); printm(M_STATUS, "Updating directory entry.\n"); dir = cdutil->find_parent(f = strdup(arg2)); free(f); if ((f = strrchr(arg2, '/'))) { f++; } else { f = arg2; } d = cdutil->find_dir_entry(&buffer, &dir, f); d->Size = file->GetSize(); // cdutil->write_datas(buffer, GUESS, dir.Sector, dir.Size); free(buffer); } else if (!strcmp(argv[optind], "insert")) { if (ppf) { if (cdutil->open_ppf(ppf, "Created by CD-Tool") < 0) { printm(M_ERROR, "Failed to open file %s for writing.\n", ppf); throw Exit(-1); } } else { iso_w = new Output(iso_name, 0, 0); cdutil->set_iso_w(iso_w); } optind++; if ((argc - 2) != optind) { showhelp(); printm(M_ERROR, "insert needs two arguments.\n"); throw Exit(-1); } arg1 = argv[optind++]; sector = atoi(argv[optind++]); file = new Input(arg1); printm(M_STATUS, "Writing file %s at sector %i.\n", arg1, sector); cdutil->write_file(file, type, sector); } else if (!strcmp(argv[optind], "copy")) { optind++; if ((argc - 1) != optind) { showhelp(); printm(M_ERROR, "copy needs one argument.\n"); throw Exit(-1); } arg1 = argv[optind]; Output * o = new Output(arg1); isobuilder * b = new isobuilder(o); isobuilder::DirTree * root = b->setbasics(isobuilder::createpvd(cdutil)); iso_r->seek(0); b->foreword(iso_r); b->copydir(root, ".", cdutil, cdutil->rootDir); Buffer * buf = new Buffer(true); (*buf) << "Touched!\n"; b->createfile(root, buf, "TOUCHED.TXT")->setbasicsxa(); b->close(); delete o; o = 0; delete b; b = 0; delete buf; buf = 0; } else if (!strcmp(argv[optind], "lua")) { optind++; if ((argc - 1) != optind) { showhelp(); printm(M_ERROR, "lua needs one argument.\n"); throw Exit(-1); } arg1 = argv[optind]; Lua * L = new Lua(); L->open_math(); L->open_string(); LuaInput::pushconstruct(L); LuaOutput::pushconstruct(L); LuaBuffer::pushconstruct(L); Luacdutils::pushstatics(L); Luacdfile::pushstatics(L); L->push("print"); L->push(myprint); L->settable(LUA_GLOBALSINDEX); Luacdutils lcdutil(cdutil); L->push("cdutil"); lcdutil.push(L); L->settable(LUA_GLOBALSINDEX); L->load(&Input(arg1)); getchar(); } else { showhelp(); printm(M_ERROR, "Command %s unknow.\n", argv[optind]); throw Exit(-1); } return 0; } CODE_ENDS