in case of EfikaMX, optimize for size
[AROS.git] / workbench / c / Eject.c
blobf318098ca0db3f0cc27a1476bb9ad30fb42d23b8
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 Load
40 INTERNALS
42 ******************************************************************************/
44 /******************************************************************************
47 NAME
48 Load <device>
50 SYNOPSIS
51 DEVICE/A
53 LOCATION
56 FUNCTION
57 Loads media into a device. This feature is not supported by all
58 device types.
60 INPUTS
61 DEVICE -- Name of device to load media into.
63 RESULT
65 NOTES
67 EXAMPLE
69 BUGS
71 SEE ALSO
73 INTERNALS
75 ******************************************************************************/
77 int __nocommandline;
79 #include <exec/exec.h>
80 #include <dos/dos.h>
81 #include <dos/filehandler.h>
82 #include <devices/trackdisk.h>
83 #include <proto/exec.h>
84 #include <proto/dos.h>
85 #include <proto/utility.h>
87 #define NAME_BUFFER_SIZE 32
89 const TEXT version_string[] = "$VER: Eject 41.1 (26.9.2009)";
90 const TEXT template[] = "DEVICE/A";
91 const TEXT load_name[] = "Load";
94 struct Args
96 TEXT *device;
100 int main(void)
102 struct RDArgs *read_args = NULL;
103 LONG error = 0, result = RETURN_OK;
104 struct Args args = {NULL};
105 struct MsgPort *port = NULL;
106 struct IOStdReq *request = NULL;
107 ULONG signals, received;
108 struct DosList *dos_list;
109 TEXT node_name[NAME_BUFFER_SIZE];
110 UWORD i;
111 struct FileSysStartupMsg *fssm;
112 struct DeviceNode *dev_node = NULL;
113 BOOL load = FALSE;
115 port = CreateMsgPort();
116 request =
117 (struct IOStdReq *)CreateIORequest(port, sizeof(struct IOStdReq));
118 if (port == NULL || request == NULL)
119 error = IoErr();
121 if (error == 0)
123 /* Parse arguments */
125 read_args = ReadArgs(template, (APTR)&args, NULL);
126 if (read_args == NULL)
128 error = IoErr();
129 result = RETURN_ERROR;
132 /* Find out if we should eject or load media based on name of command */
134 load = Strnicmp(FilePart(AROS_BSTR_ADDR(Cli()->cli_CommandName)),
135 load_name, sizeof(load_name) - 1) == 0;
138 if (error == 0)
140 /* Make copy of DOS device name without a colon */
142 for (i = 0; args.device[i] != '\0' && args.device[i] != ':'
143 && i < NAME_BUFFER_SIZE; i++)
144 node_name[i] = args.device[i];
145 if (args.device[i] == ':' && i < NAME_BUFFER_SIZE)
146 node_name[i] = '\0';
147 else
148 error = ERROR_INVALID_COMPONENT_NAME;
151 /* Determine trackdisk-like device underlying DOS device */
153 if (error == 0)
155 dos_list = LockDosList(LDF_READ);
156 if (dos_list != NULL)
158 dev_node = (struct DeviceNode *)FindDosEntry(dos_list, node_name,
159 LDF_DEVICES);
160 if (dev_node == NULL)
161 error = IoErr();
162 UnLockDosList(LDF_READ);
164 else
165 error = IoErr();
168 if (error == 0)
170 if (IsFileSystem(args.device))
171 fssm = (struct FileSysStartupMsg *)BADDR(dev_node->dn_Startup);
172 else
173 error = ERROR_OBJECT_WRONG_TYPE;
176 /* Open trackdisk-like device */
178 if (error == 0)
180 if (OpenDevice(AROS_BSTR_ADDR(fssm->fssm_Device), fssm->fssm_Unit,
181 (APTR)request, 0) != 0)
182 error = ERROR_UNKNOWN;
185 if (error == 0)
187 /* Send command to eject or load media */
189 request->io_Command = TD_EJECT;
190 request->io_Length = load ? 0 : 1;
191 SendIO((APTR)request);
192 signals = (1 << port->mp_SigBit) | SIGBREAKF_CTRL_C;
193 received = 0;
195 /* Wait for command completion or user break */
197 while ((received & SIGBREAKF_CTRL_C) == 0 && GetMsg(port) == NULL)
198 received = Wait(signals);
199 if ((received & SIGBREAKF_CTRL_C) != 0)
201 AbortIO((APTR)request);
202 WaitIO((APTR)request);
203 GetMsg(port);
204 error = ERROR_BREAK;
205 result = RETURN_WARN;
207 else
209 if (request->io_Error != 0)
210 error = ERROR_UNKNOWN;
214 /* Deallocate resources */
216 if (request != NULL)
217 CloseDevice((APTR)request);
218 DeleteIORequest(request);
219 DeleteMsgPort(port);
221 FreeArgs(read_args);
223 /* Print any error message and return */
225 SetIoErr(error);
226 PrintFault(error, NULL);
228 if (error != 0 && result == RETURN_OK)
229 result = RETURN_FAIL;
231 return result;