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