diff options
Diffstat (limited to 'ditool.c')
-rw-r--r-- | ditool.c | 419 |
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 +*/ |