]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/cmd_attach.c
Remove extern declarations from command_tbl.c, create .h files for that.
[z180-stamp.git] / avr / cmd_attach.c
1 /*
2 * (C) Copyright 2016 Leo C. <erbl259-lmu@yahoo.de>
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7 /*
8 * attach channels to devices
9 */
10
11 #include "cmd_attach.h"
12
13 #include "command.h"
14 #include "z180-serv.h"
15 #include "getopt-min.h"
16
17
18 static const FLASH char * const FLASH rc_messages[] = {
19 FSTR("OK"),
20 FSTR("Unknown error"),
21 FSTR("Disk number out of range 0..7"),
22 FSTR("Disk allready attached"),
23 FSTR("Disk not attached"),
24 FSTR("File not found"),
25 FSTR("Not enough memory"),
26 FSTR("Error opening file"),
27 FSTR("File allready attached to other drive"),
28 };
29
30 static
31 void printerror(int rc, uint8_t unit, char *fn)
32 {
33 if (rc < 0 || (unsigned) rc >= ARRAY_SIZE(rc_messages))
34 rc = 1;
35
36 #if GCC_BUG_61443
37 printf_P(PSTR("Attachment of '%s' to dsk%d failed: "), fn, unit);
38 my_puts_P(rc_messages[rc]);
39 my_puts_P(PSTR("!\n"));
40 #else
41 printf_P(PSTR("Attachment of '%s' to dsk%d failed: %S!\n"),
42 fn, unit, rc_messages[rc]);
43 #endif
44 }
45
46 /*
47 * attach [[options] [unit [diskfile]]]
48 *
49 * detach unit
50 * attach -d unit
51 *
52 * attach -o reattach unit
53 * attach -o reattach unit diskfile
54 *
55 * attach unit diskfile
56 *
57 */
58
59 command_ret_t do_attach(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[])
60 {
61 uint8_t unit;
62 char *filename = NULL;
63 bool detach = false;
64 bool detach_all = false;
65 drv_opt_t options = 0;
66 int res;
67
68 (void) cmdtp; (void) flag;
69
70
71 if (argv[0][0] == 'd') {
72 /* we are called as 'detach' */
73 detach = true;
74 } else if (argc == 1) {
75 /* no arguments */
76 drv_list();
77 return CMD_RET_SUCCESS;
78 }
79
80 /* reset getopt() */
81 optind = 0;
82
83 int opt;
84 while ((opt = getopt(argc, argv, PSTR("darwo:"))) != -1) {
85 switch (opt) {
86 case 'd':
87 detach = true;
88 break;
89 case 'a':
90 detach_all = true;
91 break;
92 case 'r':
93 options |= DRV_OPT_RO;
94 break;
95 case 'w':
96 options &= ~DRV_OPT_RO;
97 break;
98 case 'o':
99 {
100 static const FLASH char delim[] = {", "};
101 char *p = strtok_P(optarg, delim);
102 while (p != NULL) {
103 if (!strcmp_P(p, PSTR("ro")))
104 options |= DRV_OPT_RO;
105 else if (!strcmp_P(p, PSTR("rw")))
106 options &= ~DRV_OPT_RO;
107 else if (!strcmp_P(p, PSTR("debug")))
108 options |= DRV_OPT_DEBUG;
109 else if (!strcmp_P(p, PSTR("nodebug")))
110 options &= ~DRV_OPT_DEBUG;
111 else if (!strcmp_P(p, PSTR("reattach")))
112 options |= DRV_OPT_REATTATCH;
113 else
114 return CMD_RET_USAGE;
115
116 p = strtok_P(NULL, delim);
117 }
118 }
119 break;
120 default: /* '?' */
121 return CMD_RET_USAGE;
122 }
123 }
124
125 /* remaining arguments */
126 argc -= optind;
127 if ( !( (argc == 0 && detach && detach_all) ||
128 (argc == 1 && detach) ||
129 (argc == 1 && (options & DRV_OPT_REATTATCH)) ||
130 argc == 2) )
131 return CMD_RET_USAGE;
132
133 if (argc > 0 && ((strlen(argv[optind]) != 4) ||
134 strncmp_P(argv[optind], PSTR("dsk"), 3) ||
135 (unit = argv[optind][3] - '0') >= CONFIG_CPM_MAX_DRIVE)) {
136
137 printf_P(PSTR("Unknown device: '%s'\n"), argv[optind]);
138 return CMD_RET_FAILURE;
139 }
140
141 if (detach) {
142 if (detach_all)
143 for (uint8_t i = 0; i < CONFIG_CPM_MAX_DRIVE; i++)
144 drv_detach(i);
145 else
146 drv_detach(unit);
147 return CMD_RET_SUCCESS;
148 }
149
150 if (argc == 2)
151 filename = argv[++optind];
152
153 res = drv_attach(unit, filename, options);
154 if (res)
155 printerror(res, unit, filename);
156
157 return res ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
158 }