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.
40 ******************************************************************************/
42 /******************************************************************************
55 Loads media into a device. This feature is not supported by all
59 DEVICE -- Name of device to load media into.
73 ******************************************************************************/
77 #include <exec/exec.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";
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
];
109 struct FileSysStartupMsg
*fssm
;
110 struct DeviceNode
*dev_node
= NULL
;
113 port
= CreateMsgPort();
115 (struct IOStdReq
*)CreateIORequest(port
, sizeof(struct IOStdReq
));
116 if (port
== NULL
|| request
== NULL
)
121 /* Parse arguments */
123 read_args
= ReadArgs(template, (APTR
)&args
, NULL
);
124 if (read_args
== NULL
)
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;
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
)
146 error
= ERROR_INVALID_COMPONENT_NAME
;
149 /* Determine trackdisk-like device underlying DOS device */
153 dos_list
= LockDosList(LDF_READ
);
154 if (dos_list
!= NULL
)
156 dev_node
= (struct DeviceNode
*)FindDosEntry(dos_list
, node_name
,
158 if (dev_node
== NULL
)
160 UnLockDosList(LDF_READ
);
168 if (IsFileSystem(args
.device
))
169 fssm
= (struct FileSysStartupMsg
*)BADDR(dev_node
->dn_Startup
);
171 error
= ERROR_OBJECT_WRONG_TYPE
;
174 /* Open trackdisk-like device */
178 if (OpenDevice(AROS_BSTR_ADDR(fssm
->fssm_Device
), fssm
->fssm_Unit
,
179 (APTR
)request
, 0) != 0)
180 error
= ERROR_UNKNOWN
;
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
;
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
);
203 result
= RETURN_WARN
;
207 if (request
->io_Error
!= 0)
208 error
= ERROR_UNKNOWN
;
212 /* Deallocate resources */
215 CloseDevice((APTR
)request
);
216 DeleteIORequest(request
);
221 /* Print any error message and return */
224 PrintFault(error
, NULL
);
226 if (error
!= 0 && result
== RETURN_OK
)
227 result
= RETURN_FAIL
;