/* * (C) Copyright 2016 Leo C. * * SPDX-License-Identifier: GPL-2.0 */ /* * attach channels to devices */ #include "common.h" #include #include #include "command.h" #include "z180-serv.h" #include "getopt-min.h" static const FLASH char * const FLASH rc_messages[] = { FSTR("OK"), FSTR("Unknown error"), FSTR("Disk number out of range 0..7"), FSTR("Disk allready attached"), FSTR("Disk not attached"), FSTR("File not found"), FSTR("Not enough memory"), FSTR("Error opening file"), FSTR("File allready attached to other drive"), }; static void printerror(int rc, uint8_t unit, char *fn) { if (rc < 0 || (unsigned) rc >= ARRAY_SIZE(rc_messages)) rc = 1; #if GCC_BUG_61443 printf_P(PSTR("Attachment of '%s' to dsk%d failed: "), fn, unit); my_puts_P(rc_messages[rc]); my_puts_P(PSTR("!\n")); #else printf_P(PSTR("Attachment of '%s' to dsk%d failed: %S!\n"), fn, unit, rc_messages[rc]); #endif } /* * attach [[options] [unit [diskfile]]] * * detach unit * attach -d unit * * attach -o reattach unit * attach -o reattach unit diskfile * * attach unit diskfile * */ command_ret_t do_attach(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint8_t unit; char *filename = NULL; bool detach = false; bool detach_all = false; drv_opt_t options = 0; int res; (void) cmdtp; (void) flag; if (argv[0][0] == 'd') { /* we are called as 'detach' */ detach = true; } else if (argc == 1) { /* no arguments */ drv_list(); return CMD_RET_SUCCESS; } /* reset getopt() */ optind = 0; int opt; while ((opt = getopt(argc, argv, PSTR("darwo:"))) != -1) { switch (opt) { case 'd': detach = true; break; case 'a': detach_all = true; break; case 'r': options |= DRV_OPT_RO; break; case 'w': options &= ~DRV_OPT_RO; break; case 'o': { static const FLASH char delim[] = {", "}; char *p = strtok_P(optarg, delim); while (p != NULL) { if (!strcmp_P(p, PSTR("ro"))) options |= DRV_OPT_RO; else if (!strcmp_P(p, PSTR("rw"))) options &= ~DRV_OPT_RO; else if (!strcmp_P(p, PSTR("debug"))) options |= DRV_OPT_DEBUG; else if (!strcmp_P(p, PSTR("nodebug"))) options &= ~DRV_OPT_DEBUG; else if (!strcmp_P(p, PSTR("reattach"))) options |= DRV_OPT_REATTATCH; else return CMD_RET_USAGE; p = strtok_P(NULL, delim); } } break; default: /* '?' */ return CMD_RET_USAGE; } } /* remaining arguments */ argc -= optind; if ( !( (argc == 0 && detach && detach_all) || (argc == 1 && detach) || (argc == 1 && (options & DRV_OPT_REATTATCH)) || argc == 2) ) return CMD_RET_USAGE; if (argc > 0 && ((strlen(argv[optind]) != 4) || strncmp_P(argv[optind], PSTR("dsk"), 3) || (unit = argv[optind][3] - '0') >= CONFIG_CPM_MAX_DRIVE)) { printf_P(PSTR("Unknown device: '%s'\n"), argv[optind]); return CMD_RET_FAILURE; } if (detach) { if (detach_all) for (uint8_t i = 0; i < CONFIG_CPM_MAX_DRIVE; i++) drv_detach(i); else drv_detach(unit); return CMD_RET_SUCCESS; } if (argc == 2) filename = argv[++optind]; res = drv_attach(unit, filename, options); if (res) printerror(res, unit, filename); return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS; }