summaryrefslogtreecommitdiff
path: root/cd-tool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cd-tool.cpp')
-rw-r--r--cd-tool.cpp612
1 files changed, 304 insertions, 308 deletions
diff --git a/cd-tool.cpp b/cd-tool.cpp
index 888cf9a..6f19d79 100644
--- a/cd-tool.cpp
+++ b/cd-tool.cpp
@@ -17,15 +17,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* $Id: cd-tool.cpp,v 1.22 2004-02-29 17:44:42 pixel Exp $ */
+/* $Id: cd-tool.cpp,v 1.23 2004-04-27 17:53:04 pixel Exp $ */
#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <string.h>
+#include <readline/readline.h>
+#include <readline/history.h>
#include "Input.h"
#include "Output.h"
#include "Buffer.h"
@@ -39,85 +35,202 @@
#include "luacd.h"
#include "luapsx.h"
+bool interactive = false;
+cdutils * cdutil = 0;
+isobuilder * build = 0;
+
static int myprint(lua_State * _L) {
Lua * L = Lua::find(_L);
String t = L->tostring();
- Base::printm(M_INFO, "From LUA: " + t + "\n");
+ Base::printm(M_STATUS, "From LUA: " + t + "\n");
return 0;
}
+class Luacdtool : public LuaObject {
+ public:
+ static void pushstatics(Lua *) throw (GeneralException);
+};
+
+typedef void cdtool;
+
+enum cdtool_functions_t {
+ CDTOOL_PRINT = 0,
+ CDTOOL_QUIT,
+ CDTOOL_EXIT,
+ CDTOOL_INFOS,
+ CDTOOL_PATH,
+ CDTOOL_PRINTDIR,
+};
+
+struct lua_functypes_t cdtool_functions[] = {
+ { CDTOOL_PRINT, "print", 1, 1, { LUA_STRING } },
+ { CDTOOL_QUIT, "quit", 0, 0, { } },
+ { CDTOOL_EXIT, "exit", 0, 0, { } },
+ { CDTOOL_INFOS, "infos", 0, 1, { LUA_OBJECT } },
+ { CDTOOL_PATH, "path", 0, 1, { LUA_OBJECT } },
+ { CDTOOL_PRINTDIR, "printdir", 1, 2, { LUA_STRING, LUA_OBJECT } },
+ { -1, 0, 0, 0, 0 }
+};
+
+class sLua_cdtool : public Base {
+ public:
+ DECLARE_FUNCTION(cdtool, CDTOOL_PRINT);
+ DECLARE_FUNCTION(cdtool, CDTOOL_QUIT);
+ DECLARE_FUNCTION(cdtool, CDTOOL_EXIT);
+ DECLARE_FUNCTION(cdtool, CDTOOL_INFOS);
+ DECLARE_FUNCTION(cdtool, CDTOOL_PATH);
+ DECLARE_FUNCTION(cdtool, CDTOOL_PRINTDIR);
+ private:
+ static int cdtool_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luacdtool::pushstatics(Lua * L) throw (GeneralException ) {
+ CHECK_FUNCTIONS(cdtool);
+
+ PUSH_FUNCTION(cdtool, CDTOOL_PRINT);
+ PUSH_FUNCTION(cdtool, CDTOOL_QUIT);
+ PUSH_FUNCTION(cdtool, CDTOOL_EXIT);
+ PUSH_FUNCTION(cdtool, CDTOOL_INFOS);
+ PUSH_FUNCTION(cdtool, CDTOOL_PATH);
+ PUSH_FUNCTION(cdtool, CDTOOL_PRINTDIR);
+}
+
+int sLua_cdtool::cdtool_proceed_statics(Lua * L, int n, int caller) {
+ int r = 0;
+ String p;
+ cdutils * cd = cdutil;
+
+ switch (caller) {
+ case CDTOOL_PRINT:
+ p = L->tostring(1);
+ printm(M_BARE, p + "\n");
+ break;
+ case CDTOOL_QUIT:
+ case CDTOOL_EXIT:
+ interactive = false;
+ break;
+ case CDTOOL_INFOS:
+ if (n)
+ cd = (cdutils *) LuaObject::getme(L, 1);
+ if (cd)
+ cd->show_iso_infos();
+ else
+ L->error("Cdutils object void");
+ break;
+ case CDTOOL_PATH:
+ if (n)
+ cd = (cdutils *) LuaObject::getme(L, 1);
+ if (cd)
+ cd->show_pt_infos();
+ else
+ L->error("Cdutils object void");
+ break;
+ case CDTOOL_PRINTDIR:
+ p = L->tostring(1);
+ if (n == 2)
+ cd = (cdutils *) LuaObject::getme(L, 2);
+ if (cd) {
+ char * f;
+ cdutils::DirEntry dir = cd->find_path(f = p.strdup());
+ free(f);
+ if (!dir.R)
+ L->error("Path `" + p + "' not found");
+ if (!(dir.Flags & 2))
+ L->error("Path `" + p + "' points to a file");
+ cd->show_head_entry();
+ cd->show_dir(&dir);
+ } else
+ L->error("Cdutils object void");
+ break;
+ }
+
+ return r;
+}
+
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'},
- {"debug", 0, NULL, 'g'},
- {"archive", 1, NULL, 'a'},
- {0, 0, NULL, 0 }
+ {"help", 0, NULL, 'h'},
+ {"verbose", 0, NULL, 'v'},
+ {"file", 1, NULL, 'f'},
+ {"output", 1, NULL, 'o'},
+ {"archive", 1, NULL, 'a'},
+ {"compile", 1, NULL, 'c'},
+ {"debug", 0, NULL, 'd'},
+ {"interactive", 0, NULL, 'i'},
+ {"line", 0, NULL, 'l'},
+ {"exec", 1, NULL, 'e'},
+ {"probe", 0, NULL, 'p'},
+ {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;
-Lua * startlua(void) {
+/* That's the basic lua starter for non interactive mode */
+Lua * start_basic_lua(void) {
Lua * L = new Lua();
+
L->open_base();
L->open_math();
L->open_string();
L->open_table();
+
LuaInput::pushconstruct(L);
LuaOutput::pushconstruct(L);
LuaBuffer::pushconstruct(L);
+
CD_PUSHSTATICS(L);
+
Luapsx::pushstatics(L);
+
L->push("print");
L->push(myprint);
- L->settable(LUA_GLOBALSINDEX);
+ L->setvar();
+
+ return L;
+}
+
+/* That's the extended stuff for interactive mode */
+Lua * start_full_lua(void) {
+ Lua * L = start_basic_lua();
+
+ Luacdtool::pushstatics(L);
+
return L;
}
-void showhelp(void) {
+void showhelp(bool longhelp = false) {
printm(M_BARE,
"Usage:\n"
-"%s [-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, 5 for Raw, and 6 for autodetect (default)\n"
+"%s [options] [lua-script1] [lua-script2] ...\n"
+"\n"
+"Options:\n"
+" -v for verbose mode.\n"
+" -f <iso> to load an initial iso file (object cdutil).\n"
+" -o <iso> to start creating an output iso (object iso).\n"
+" -a <paq> to load an additionnal archive file.\n"
+" -c <out> to dump the compiled byte code to file.\n"
+" -d to enable debug mode (ie, do not strip)\n"
+" -i to start interactive mode.\n"
+" -l to turn off the no exec on end line.\n"
+" -e <cmd> to execute this single command in LUA.\n"
+" -h for this help page.\n"
+, argv[0]);
+
+ if (longhelp)
+ printm(M_BARE,
+"\n"
+"Verbose mode can be somewhat a floody thing.\n"
+"Options -i/-e and -c are mutually exclusive.\n"
+"Options -i and -e are NOT mutually exclusive. For example:\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"
-#if 0
-" copy <isofile> - copy to another iso\n"
-#endif
-" lua <luascript> - interpret single LUA script\n"
-" luapatch <luapatch> <file> - create a new iso file using the LUA script\n"
-" luacomp <luascript> <file> - compile a LUA script\n"
+" $ %s -i -e \"main()\" somescript.lua\n"
"\n"
-"Additional options:\n"
-" -v for verbose mode.\n"
-" -g for LUA compiling debug mode (ie, no stripping)\n"
-" -a to load an additionnal archive file\n"
-" -h for this help page\n"
+"This will first load the script 'somescript.lua', then execute main, and\n"
+"afterward, start the interactive mode.\n"
+"\n"
+"If a script contains inlined code, it will be run right after loading.\n"
, argv[0]);
}
@@ -138,297 +251,180 @@ void probe(void) {
}
virtual int startup() throw (GeneralException) {
- int type = GUESS, c, size, force = 0, sector;
- char * ppf = 0, * iso_name = 0, * arg1 = 0, * arg2 = 0, * f;
- bool debug = false;
+ char c;
+
+ bool auto_exec = false, strip = true, todo = false, runit;
+ char * file = 0, * output = 0, * compile = 0, * exec = 0, * line_read = 0;
+ char prompt[10];
+ Lua * L = 0;
+ Output * build_iso = 0;
+ Buffer command;
+ String line, endline;
+ int pos;
- verbosity = M_WARNING;
+ verbosity = M_STATUS;
- while ((c = getopt_long(argc, argv, "Hhm:p:fvga:", long_options, NULL)) != EOF) {
+ /* Let's start parsing options */
+
+ while ((c = getopt_long(argc, argv, "Hhvf:o:a:c:dile:pm:", 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);
+ case 'v':
+ verbosity = M_INFO;
break;
case 'f':
- force = 1;
+ file = strdup(optarg);
+ break;
+ case 'o':
+ output = strdup(optarg);
break;
- case 'v':
- verbosity = M_INFO;
- break;
- case 'g':
- debug = true;
- break;
case 'a':
new Archive(optarg);
break;
+ case 'c':
+ compile = strdup(optarg);
+ break;
+ case 'd':
+ strip = false;
+ break;
+ case 'i':
+ interactive = true;
+ todo = true;
+ break;
+ case 'l':
+ auto_exec = true;
+ break;
+ case 'e':
+ exec = strdup(optarg);
+ todo = true;
+ break;
+ case 'p':
+ probe();
+ throw Exit(0);
+ default:
+ showhelp();
+ throw Exit(-1);
}
}
- if (argc == optind) {
+ if (interactive)
+ L = start_full_lua();
+ else
+ L = start_basic_lua();
+
+ /* Loading all the scripts */
+ while (optind < argc) {
+ todo = true;
+ L->load(&Input(argv[optind++]), compile);
+ }
+
+ /* Doh... */
+ if (!todo) {
showhelp();
- printm(M_ERROR, "Need an iso filename to work on.\n");
- exit(-1);
+ throw Exit(0);
}
- iso_name = argv[optind++];
-
- if (!strcmp(iso_name, "probe")) {
- probe();
- exit(-1);
+ /* Compilation process will exit from itself right after */
+ if (compile) {
+ L->dump(&Output(compile), strip);
+ throw Exit(0);
}
- if (argc == optind) {
- showhelp();
- printm(M_ERROR, "Need a command to execute.\n");
- exit(-1);
+ /* The basic input (and eventually output) iso file */
+ if (file) {
+ cdutil = new cdutils(cdabstract::open_cd(file));
+ if (!cdutil->get_iso_infos())
+ throw Exit(-1);
+ Luacdutils lcdutil(cdutil);
+ L->push("cdutil");
+ lcdutil.push(L);
+ L->setvar();
}
- iso_r = cdabstract::open_cd(iso_name);
+ /* The generated iso file */
+ if (output) {
+ build_iso = new Output(output);
+ build = new isobuilder(build_iso);
+ Luaisobuilder lbuild(build);
+ L->push("iso");
+ lbuild.push(L);
+ L->setvar();
+ }
- cdutil = new cdutils(iso_r);
+ /* One shot command */
+ if (exec) {
+ command << exec;
+ L->load(&command);
+ }
- 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;
+ /* Interactive mode loop */
+ strcpy(prompt, "> ");
+ rl_bind_key('\t', rl_insert);
+ while (interactive) {
+ /* Basic usage of readline */
+ if (line_read)
+ free(line_read);
- 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, dir->Size, type, dir->Sector);
-#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, size, type, sector);
- } else if (!strcmp(argv[optind], "insert-file")) {
- cdutils::DirEntry dir, * d;
- unsigned char * buffer;
- int old_type;
+ line_read = readline(prompt);
- 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);
- }
+ if (line_read && *line_read)
+ add_history(line_read);
- 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);
- }
+ line = line_read;
+ line = line.trim();
+ endline = "";
- old_type = cdutil->guess_type(dir.Sector);
+ /* Splitting the line between ;; */
+ while (line.strlen()) {
+ runit = false;
- 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());
+ if ((pos = line.strstr(";;")) >= 0) {
+ endline = line.extract(pos + 2);
+ line = line.extract(0, pos);
+ runit = true;
} else {
- printm(M_ERROR, "New file too big: %i vs %i in " + sec_modes[type] + ".\n", dir.Size, file->GetSize());
- throw Exit(-1);
+ endline = "";
}
- }
- printm(M_STATUS, "Writing file %s at path %s (sector %i).\n", arg1, arg2, dir.Sector);
- cdutil->write_file(file, -1, 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);
+
+ if (line[line.strlen() - 1] == '\\') {
+ line[line.strlen() - 1] = ' ';
+ } else if (auto_exec) {
+ runit = true;
}
- } else {
- iso_w = new Output(iso_name, 0, 0);
- cdutil->set_iso_w(iso_w);
- }
+
+ command << line;
- 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, -1, 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 = startlua();
- Luacdutils lcdutil(cdutil);
- L->push("cdutil");
- lcdutil.push(L);
- L->settable(LUA_GLOBALSINDEX);
- L->load(&Input(arg1));
- delete L;
- } else if (!strcmp(argv[optind], "luapatch")) {
- optind++;
- if ((argc - 2) != optind) {
- showhelp();
- printm(M_ERROR, "luapatch needs two arguments.\n");
- throw Exit(-1);
- }
- arg1 = argv[optind++];
- arg2 = argv[optind];
- Output * o = new Output(arg2);
- isobuilder * b;
- if (type == GUESS)
- b = new isobuilder(o);
- else
- b = new isobuilder(o, type);
- Lua * L = startlua();
- Luacdutils lcdutil(cdutil);
- L->push("cdutil");
- lcdutil.push(L);
- L->setvar();
- Luaisobuilder liso(b);
- L->push("iso");
- liso.push(L);
- L->setvar();
- L->load(&Input(arg1));
- delete L;
- delete b;
- delete o;
- } else if (!strcmp(argv[optind], "luacomp")) {
- optind++;
- if ((argc - 2) != optind) {
- showhelp();
- printm(M_ERROR, "luacomp needs two arguments.\n");
- throw Exit(-1);
- }
- arg1 = argv[optind++];
- arg2 = argv[optind];
- Output * o = new Output(arg2);
- Lua * L = new Lua();
- L->load(&Input(arg1), false);
- L->dump(o, !debug);
- delete L;
- delete o;
- } else {
- showhelp();
- printm(M_ERROR, "Command %s unknow.\n", argv[optind]);
- throw Exit(-1);
+ if (runit) {
+ try {
+ L->load(&command);
+ }
+ catch (GeneralException e) {
+ /* If there was an error, ignore it, and free the stack */
+ while(L->gettop())
+ L->pop();
+ }
+ strcpy(prompt, "> ");
+ } else {
+ strcpy(prompt, "- ");
+ }
+ line = endline.trim();
+ };
+ }
+
+ /* Finishing off the work, cleaning out the dust */
+ if (output) {
+ delete build_iso;
+ delete build;
}
+
+ if (file) {
+ delete cdutil;
+ }
+
return 0;
}
CODE_ENDS