Hint added.
[AROS.git] / workbench / c / Eject.c
blob71c961b5ed3001db442841e0b2f213f3d864e48e
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
88 #ifndef ERROR_UNKNOWN
89 #define ERROR_UNKNOWN 100
90 #define AROS_BSTR_ADDR(s) (((STRPTR)BADDR(s))+1)
91 #endif
93 const TEXT version_string[] = "$VER: Eject 41.1 (26.9.2009)";
94 const TEXT template[] = "DEVICE/A";
95 const TEXT load_name[] = "Load";
98 struct Args
100 TEXT *device;
104 int main(void)
106 struct RDArgs *read_args = NULL;
107 LONG error = 0, result = RETURN_OK;
108 struct Args args = {NULL};
109 struct MsgPort *port = NULL;
110 struct IOStdReq *request = NULL;
111 ULONG signals, received;
112 struct DosList *dos_list;
113 TEXT node_name[NAME_BUFFER_SIZE];
114 UWORD i;
115 struct FileSysStartupMsg *fssm;
116 struct DeviceNode *dev_node = NULL;
117 BOOL load = FALSE;
119 port = CreateMsgPort();
120 request =
121 (struct IOStdReq *)CreateIORequest(port, sizeof(struct IOStdReq));
122 if (port == NULL || request == NULL)
123 error = IoErr();
125 if (error == 0)
127 /* Parse arguments */
129 read_args = ReadArgs(template, (APTR)&args, NULL);
130 if (read_args == NULL)
132 error = IoErr();
133 result = RETURN_ERROR;
136 /* Find out if we should eject or load media based on name of command */
138 load = Strnicmp(FilePart(AROS_BSTR_ADDR(Cli()->cli_CommandName)),
139 load_name, sizeof(load_name) - 1) == 0;
142 if (error == 0)
144 /* Make copy of DOS device name without a colon */
146 for (i = 0; args.device[i] != '\0' && args.device[i] != ':'
147 && i < NAME_BUFFER_SIZE; i++)
148 node_name[i] = args.device[i];
149 if (args.device[i] == ':' && i < NAME_BUFFER_SIZE)
150 node_name[i] = '\0';
151 else
152 error = ERROR_INVALID_COMPONENT_NAME;
155 /* Determine trackdisk-like device underlying DOS device */
157 if (error == 0)
159 dos_list = LockDosList(LDF_READ);
160 if (dos_list != NULL)
162 dev_node = (struct DeviceNode *)FindDosEntry(dos_list, node_name,
163 LDF_DEVICES);
164 if (dev_node == NULL)
165 error = IoErr();
166 UnLockDosList(LDF_READ);
168 else
169 error = IoErr();
172 if (error == 0)
174 if (IsFileSystem(args.device))
175 fssm = (struct FileSysStartupMsg *)BADDR(dev_node->dn_Startup);
176 else
177 error = ERROR_OBJECT_WRONG_TYPE;
180 /* Open trackdisk-like device */
182 if (error == 0)
184 if (OpenDevice(AROS_BSTR_ADDR(fssm->fssm_Device), fssm->fssm_Unit,
185 (APTR)request, 0) != 0)
186 error = ERROR_UNKNOWN;
189 if (error == 0)
191 /* Send command to eject or load media */
193 request->io_Command = TD_EJECT;
194 request->io_Length = load ? 0 : 1;
195 SendIO((APTR)request);
196 signals = (1 << port->mp_SigBit) | SIGBREAKF_CTRL_C;
197 received = 0;
199 /* Wait for command completion or user break */
201 while ((received & SIGBREAKF_CTRL_C) == 0 && GetMsg(port) == NULL)
202 received = Wait(signals);
203 if ((received & SIGBREAKF_CTRL_C) != 0)
205 AbortIO((APTR)request);
206 WaitIO((APTR)request);
207 GetMsg(port);
208 error = ERROR_BREAK;
209 result = RETURN_WARN;
211 else
213 if (request->io_Error != 0)
214 error = ERROR_UNKNOWN;
218 /* Deallocate resources */
220 if (request != NULL)
221 CloseDevice((APTR)request);
222 DeleteIORequest(request);
223 DeleteMsgPort(port);
225 FreeArgs(read_args);
227 /* Print any error message and return */
229 SetIoErr(error);
230 PrintFault(error, NULL);
232 if (error != 0 && result == RETURN_OK)
233 result = RETURN_FAIL;
235 return result;