summaryrefslogtreecommitdiff
path: root/ditool.c
diff options
context:
space:
mode:
Diffstat (limited to 'ditool.c')
-rw-r--r--ditool.c419
1 files changed, 419 insertions, 0 deletions
diff --git a/ditool.c b/ditool.c
new file mode 100644
index 0000000..8254650
--- /dev/null
+++ b/ditool.c
@@ -0,0 +1,419 @@
+/*
+
+ DiskImageTool - Tool for manipulating disk images
+
+ Copyright (C) 2019 Ian Cowburn (ianc@noddybox.co.uk)
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+
+ -------------------------------------------------------------------------
+
+ Main
+
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "util.h"
+#include "handler.h"
+#include "cpc.h"
+
+/* ---------------------------------------- MACROS
+*/
+
+
+/* ---------------------------------------- VERSION INFO
+*/
+
+static const char *ditool_version =
+"Disk Image Tool Version 1.0 development\n"
+"\n"
+"This program is distributed in the hope that it will be useful,\n"
+"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+"GNU General Public License (Version 3) for more details.\n"
+"\n";
+
+
+/* ---------------------------------------- TYPES
+*/
+
+/* ---------------------------------------- GLOBALS
+*/
+static int g_no_handlers;
+static Handler *g_handler;
+static Handler *g_current;
+static int g_open = 0;
+
+/* ---------------------------------------- DISK HANDLER REGISTER
+*/
+
+static void DITOOL_Initialise(void)
+{
+ CPC_Initialise();
+}
+
+void DITOOL_Register(const Handler *handler)
+{
+ g_no_handlers++;
+ g_handler = Realloc(g_handler, sizeof *g_handler * g_no_handlers);
+ g_handler[g_no_handlers - 1] = *handler;
+}
+
+/* ---------------------------------------- COMMAND ROUTINES
+*/
+static void Help(void)
+{
+ printf(
+"handlers - List available disk image handlers.\n"
+"current <handler> - Set current handler.\n"
+"open <file> - Try and open disk image. Changes current handler.\n"
+"close [<file>] - Close the current disk image. If the optional name\n"
+" name is provided the image is saved to that file.\n"
+"create <file> - Create new disk image using current handler.\n"
+"ls - List files in disk image.\n"
+"info - Get info on the disk image.\n"
+"get <name> <file> - Get named file from disk image and store it in file.\n"
+"put <name> <file> - Put file into disk image calling it name.\n"
+"delete <name> - Delete named file from disk image.\n"
+"quit - Quit.\n"
+);
+}
+
+static void Current(char * const tok[])
+{
+ int f;
+ int found = 0;
+
+ if (tok[1])
+ {
+ for(f = 0; f < g_no_handlers; f++)
+ {
+ if (strcmp(g_handler[f].id, tok[1]) == 0)
+ {
+ if (g_open && g_current)
+ {
+ g_current->close_image(NULL);
+ g_open = 0;
+ }
+
+ g_current = g_handler + f;
+ found = 1;
+ printf("Set current handler to %s\n",
+ g_current->name);
+ }
+ }
+
+ if (!found)
+ {
+ printf("unknown handler %s\n", tok[1]);
+ }
+ }
+ else
+ {
+ printf("Missing argument\n");
+ }
+}
+
+static void Handlers(char * const tok[])
+{
+ int f;
+
+ for(f = 0; f < g_no_handlers; f++)
+ {
+ printf("%s - %s\n", g_handler[f].id, g_handler[f].name);
+ }
+}
+
+static void Open(char * const tok[])
+{
+ if (tok[1])
+ {
+ void *mem;
+ size_t size;
+
+ mem = Load(tok[1], &size);
+
+ if (mem)
+ {
+ int f;
+
+ if (g_open && g_current)
+ {
+ g_current->close_image(NULL);
+ g_open = 0;
+ }
+
+ g_current = NULL;
+
+ for(f = 0; f < g_no_handlers && !g_current; f++)
+ {
+ if (g_handler[f].is_my_file(mem, size))
+ {
+ g_current = g_handler + f;
+ }
+ }
+
+ if (g_current)
+ {
+ if (g_current->open_image(mem, size))
+ {
+ g_open = 1;
+ printf("Set current handler to %s\n",
+ g_current->name);
+ }
+ else
+ {
+ g_open = 0;
+ printf("%s\n", g_current->last_error());
+ }
+ }
+ else
+ {
+ free(mem);
+ printf("No handler for file %s\n", tok[1]);
+ }
+ }
+ else
+ {
+ printf("Failed to open %s\n", tok[1]);
+ }
+ }
+ else
+ {
+ printf("Missing argument\n");
+ }
+}
+
+static void Close(char * const tok[])
+{
+ if (g_open && g_current)
+ {
+ g_current->close_image(tok[1]);
+ g_open = 0;
+ }
+ else
+ {
+ printf("No open image\n");
+ }
+}
+
+static void Create(char * const tok[])
+{
+ if (tok[1])
+ {
+ if (g_current)
+ {
+ if (g_open)
+ {
+ g_current->close_image(NULL);
+ g_open = 0;
+ }
+
+ if (!g_current->create(tok[1]))
+ {
+ printf("%s\n", g_current->last_error());
+ }
+ }
+ else
+ {
+ printf("No current handler\n");
+ }
+ }
+ else
+ {
+ printf("Missing argument\n");
+ }
+}
+
+static void Ls(char * const tok[])
+{
+ if (g_current && g_open)
+ {
+ g_current->list_files();
+ }
+ else
+ {
+ printf("No open image\n");
+ }
+}
+
+static void Info(char * const tok[])
+{
+ if (g_current && g_open)
+ {
+ g_current->list_info();
+ }
+ else
+ {
+ printf("No open image\n");
+ }
+}
+
+static void Get(char * const tok[])
+{
+ if (tok[2])
+ {
+ if (g_current && g_open)
+ {
+ if (!g_current->get_file(tok[1], tok[2]))
+ {
+ printf("%s\n", g_current->last_error());
+ }
+ }
+ else
+ {
+ printf("No open image\n");
+ }
+ }
+ else
+ {
+ printf("Missing arguments\n");
+ }
+}
+
+static void Put(char * const tok[])
+{
+ if (tok[2])
+ {
+ if (g_current && g_open)
+ {
+ if (!g_current->put_file(tok[1], tok[2]))
+ {
+ printf("%s\n", g_current->last_error());
+ }
+ }
+ else
+ {
+ printf("No open image\n");
+ }
+ }
+ else
+ {
+ printf("Missing arguments\n");
+ }
+}
+
+static void Delete(char * const tok[])
+{
+ if (tok[1])
+ {
+ if (g_current && g_open)
+ {
+ if (!g_current->delete_file(tok[1]))
+ {
+ printf("%s\n", g_current->last_error());
+ }
+ }
+ else
+ {
+ printf("No open image\n");
+ }
+ }
+ else
+ {
+ printf("Missing argument\n");
+ }
+}
+
+/* ---------------------------------------- MAIN
+*/
+int main(int argc, char *argv[])
+{
+ char buff[1024];
+ int quit = 0;
+
+ printf("%s", ditool_version);
+ printf("Type help for help\n");
+
+ DITOOL_Initialise();
+
+ while(!quit && GetLine(g_current ? g_current->id : "DITOOL",
+ buff, sizeof buff))
+ {
+ char *tok[3] = {0};
+
+ tok[0] = strtok(buff, " \t");
+
+ if (tok[0])
+ {
+ tok[1] = strtok(NULL, " \t");
+
+ if (tok[1])
+ {
+ tok[2] = strtok(NULL, " \t");
+ }
+
+ if (strcmp(tok[0], "quit") == 0)
+ {
+ quit = 1;
+ }
+ else if (strcmp(tok[0], "help") == 0 || strcmp(tok[0], "?") == 0)
+ {
+ Help();
+ }
+ else if (strcmp(tok[0], "current") == 0)
+ {
+ Current(tok);
+ }
+ else if (strcmp(tok[0], "handlers") == 0)
+ {
+ Handlers(tok);
+ }
+ else if (strcmp(tok[0], "open") == 0)
+ {
+ Open(tok);
+ }
+ else if (strcmp(tok[0], "close") == 0)
+ {
+ Close(tok);
+ }
+ else if (strcmp(tok[0], "create") == 0)
+ {
+ Create(tok);
+ }
+ else if (strcmp(tok[0], "ls") == 0)
+ {
+ Ls(tok);
+ }
+ else if (strcmp(tok[0], "info") == 0)
+ {
+ Info(tok);
+ }
+ else if (strcmp(tok[0], "get") == 0)
+ {
+ Get(tok);
+ }
+ else if (strcmp(tok[0], "put") == 0)
+ {
+ Put(tok);
+ }
+ else if (strcmp(tok[0], "delete") == 0)
+ {
+ Delete(tok);
+ }
+ else
+ {
+ printf("unknown command %s - type help for help\n", tok[0]);
+ }
+ }
+ }
+
+ return EXIT_SUCCESS;
+}
+
+/*
+vim: ai sw=4 ts=8 expandtab
+*/