2 Copyright © 2009, The AROS Development Team. All rights reserved.
5 Desc: Eject/Load CLI command.
9 /******************************************************************************
22 Ejects media from a device. This feature is not supported by all
26 DEVICE -- Name of device to eject media from.
42 ******************************************************************************/
44 /******************************************************************************
57 Loads media into a device. This feature is not supported by all
61 DEVICE -- Name of device to load media into.
75 ******************************************************************************/
79 #include <exec/exec.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 #define ERROR_UNKNOWN 100
90 #define AROS_BSTR_ADDR(s) (((STRPTR)BADDR(s))+1)
93 const TEXT version_string
[] = "$VER: Eject 41.1 (26.9.2009)";
94 const TEXT
template[] = "DEVICE/A";
95 const TEXT load_name
[] = "Load";
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
];
115 struct FileSysStartupMsg
*fssm
;
116 struct DeviceNode
*dev_node
= NULL
;
119 port
= CreateMsgPort();
121 (struct IOStdReq
*)CreateIORequest(port
, sizeof(struct IOStdReq
));
122 if (port
== NULL
|| request
== NULL
)
127 /* Parse arguments */
129 read_args
= ReadArgs(template, (APTR
)&args
, NULL
);
130 if (read_args
== NULL
)
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;
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
)
152 error
= ERROR_INVALID_COMPONENT_NAME
;
155 /* Determine trackdisk-like device underlying DOS device */
159 dos_list
= LockDosList(LDF_READ
);
160 if (dos_list
!= NULL
)
162 dev_node
= (struct DeviceNode
*)FindDosEntry(dos_list
, node_name
,
164 if (dev_node
== NULL
)
166 UnLockDosList(LDF_READ
);
174 if (IsFileSystem(args
.device
))
175 fssm
= (struct FileSysStartupMsg
*)BADDR(dev_node
->dn_Startup
);
177 error
= ERROR_OBJECT_WRONG_TYPE
;
180 /* Open trackdisk-like device */
184 if (OpenDevice(AROS_BSTR_ADDR(fssm
->fssm_Device
), fssm
->fssm_Unit
,
185 (APTR
)request
, 0) != 0)
186 error
= ERROR_UNKNOWN
;
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
;
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
);
209 result
= RETURN_WARN
;
213 if (request
->io_Error
!= 0)
214 error
= ERROR_UNKNOWN
;
218 /* Deallocate resources */
221 CloseDevice((APTR
)request
);
222 DeleteIORequest(request
);
227 /* Print any error message and return */
230 PrintFault(error
, NULL
);
232 if (error
!= 0 && result
== RETURN_OK
)
233 result
= RETURN_FAIL
;