Added missing cap.
[AROS.git] / workbench / c / Eject.c
blobf25de5103a33947231ad094a978a614f08501016
1 /*
2 Copyright © 2009, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Eject/Load CLI command.
6 Lang: English
7 */
9 /******************************************************************************
12 NAME
13 Eject <device>
15 SYNOPSIS
16 DEVICE/A
18 LOCATION
21 FUNCTION
22 Ejects media from a device. This feature is not supported by all
23 device types.
25 INPUTS
26 DEVICE -- Name of device to eject media from.
28 RESULT
30 NOTES
32 EXAMPLE
34 BUGS
36 SEE ALSO
38 INTERNALS
40 ******************************************************************************/
42 /******************************************************************************
45 NAME
46 Load <device>
48 SYNOPSIS
49 DEVICE/A
51 LOCATION
54 FUNCTION
55 Loads media into a device. This feature is not supported by all
56 device types.
58 INPUTS
59 DEVICE -- Name of device to load media into.
61 RESULT
63 NOTES
65 EXAMPLE
67 BUGS
69 SEE ALSO
71 INTERNALS
73 ******************************************************************************/
75 int __nocommandline;
77 #include <exec/exec.h>
78 #include <dos/dos.h>
79 #include <dos/filehandler.h>
80 #include <devices/trackdisk.h>
81 #include <proto/exec.h>
82 #include <proto/dos.h>
83 #include <proto/utility.h>
85 #define NAME_BUFFER_SIZE 32
87 const TEXT version_string[] = "$VER: Eject 41.1 (26.9.2009)";
88 const TEXT template[] = "DEVICE/A";
89 const TEXT load_name[] = "Load";
92 struct Args
94 TEXT *device;
98 int main(void)
100 struct RDArgs *read_args = NULL;
101 LONG error = 0, result = RETURN_OK;
102 struct Args args = {NULL};
103 struct MsgPort *port = NULL;
104 struct IOStdReq *request = NULL;
105 ULONG signals, received;
106 struct DosList *dos_list;
107 TEXT node_name[NAME_BUFFER_SIZE];
108 UWORD i;
109 struct FileSysStartupMsg *fssm;
110 struct DeviceNode *dev_node = NULL;
111 BOOL load = FALSE;
113 port = CreateMsgPort();
114 request =
115 (struct IOStdReq *)CreateIORequest(port, sizeof(struct IOStdReq));
116 if (port == NULL || request == NULL)
117 error = IoErr();
119 if (error == 0)
121 /* Parse arguments */
123 read_args = ReadArgs(template, (APTR)&args, NULL);
124 if (read_args == NULL)
126 error = IoErr();
127 result = RETURN_ERROR;
130 /* Find out if we should eject or load media based on name of command */
132 load = Strnicmp(FilePart(AROS_BSTR_ADDR(Cli()->cli_CommandName)),
133 load_name, sizeof(load_name) - 1) == 0;
136 if (error == 0)
138 /* Make copy of DOS device name without a colon */
140 for (i = 0; args.device[i] != '\0' && args.device[i] != ':'
141 && i < NAME_BUFFER_SIZE; i++)
142 node_name[i] = args.device[i];
143 if (args.device[i] == ':' && i < NAME_BUFFER_SIZE)
144 node_name[i] = '\0';
145 else
146 error = ERROR_INVALID_COMPONENT_NAME;
149 /* Determine trackdisk-like device underlying DOS device */
151 if (error == 0)
153 dos_list = LockDosList(LDF_READ);
154 if (dos_list != NULL)
156 dev_node = (struct DeviceNode *)FindDosEntry(dos_list, node_name,
157 LDF_DEVICES);
158 if (dev_node == NULL)
159 error = IoErr();
160 UnLockDosList(LDF_READ);
162 else
163 error = IoErr();
166 if (error == 0)
168 if (IsFileSystem(args.device))
169 fssm = (struct FileSysStartupMsg *)BADDR(dev_node->dn_Startup);
170 else
171 error = ERROR_OBJECT_WRONG_TYPE;
174 /* Open trackdisk-like device */
176 if (error == 0)
178 if (OpenDevice(AROS_BSTR_ADDR(fssm->fssm_Device), fssm->fssm_Unit,
179 (APTR)request, 0) != 0)
180 error = ERROR_UNKNOWN;
183 if (error == 0)
185 /* Send command to eject or load media */
187 request->io_Command = TD_EJECT;
188 request->io_Length = load ? 0 : 1;
189 SendIO((APTR)request);
190 signals = (1 << port->mp_SigBit) | SIGBREAKF_CTRL_C;
191 received = 0;
193 /* Wait for command completion or user break */
195 while ((received & SIGBREAKF_CTRL_C) == 0 && GetMsg(port) == NULL)
196 received = Wait(signals);
197 if ((received & SIGBREAKF_CTRL_C) != 0)
199 AbortIO((APTR)request);
200 WaitIO((APTR)request);
201 GetMsg(port);
202 error = ERROR_BREAK;
203 result = RETURN_WARN;
205 else
207 if (request->io_Error != 0)
208 error = ERROR_UNKNOWN;
212 /* Deallocate resources */
214 if (request != NULL)
215 CloseDevice((APTR)request);
216 DeleteIORequest(request);
217 DeleteMsgPort(port);
219 FreeArgs(read_args);
221 /* Print any error message and return */
223 SetIoErr(error);
224 PrintFault(error, NULL);
226 if (error != 0 && result == RETURN_OK)
227 result = RETURN_FAIL;
229 return result;