revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / diskimage / cmd / mountdiskimage.c
blob9dd916de97f61c836955378d7eb5c2d5e3274d65
1 /* Copyright 2007-2012 Fredrik Wikstrom. All rights reserved.
2 **
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
5 ** are met:
6 **
7 ** 1. Redistributions of source code must retain the above copyright
8 ** notice, this list of conditions and the following disclaimer.
9 **
10 ** 2. Redistributions in binary form must reproduce the above copyright
11 ** notice, this list of conditions and the following disclaimer in the
12 ** documentation and/or other materials provided with the distribution.
14 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 ** POSSIBILITY OF SUCH DAMAGE.
27 #include <exec/exec.h>
28 #include <dos/dos.h>
29 #include <dos/filehandler.h>
30 #include <workbench/startup.h>
31 #include <devices/diskimage.h>
32 #include <proto/exec.h>
33 #include <proto/dos.h>
34 #include <proto/icon.h>
35 #include <proto/diskimage.h>
36 #ifdef __AROS__
37 #include <libraries/mui.h>
38 #include <proto/muimaster.h>
39 #else
40 #include <reaction/reaction_macros.h>
41 #include <classes/requester.h>
42 #include <proto/intuition.h>
43 #include <proto/requester.h>
44 #include <clib/alib_protos.h>
45 #endif
46 #include <string.h>
47 #include "support.h"
48 #include "rev/MountDiskImage_rev.h"
50 CONST TEXT USED verstag[] = VERSTAG;
52 #ifndef ACTION_GET_DISK_FSSM
53 #define ACTION_GET_DISK_FSSM 4201
54 #define ACTION_FREE_DISK_FSSM 4202
55 #endif
57 #define PROGNAME "MountDiskImage"
58 #define TEMPLATE "D=DEVICE=DRIVE/K,U=UNIT/K/N,INSERT=FILE,EJECT/S," \
59 "P=PLUGIN/K,WP=WRITEPROTECT/S,PWD=PASSWORD/K,RELOADPLUGINS/S"
61 enum {
62 ARG_DRIVE,
63 ARG_UNIT,
64 ARG_INSERT,
65 ARG_EJECT,
66 ARG_PLUGIN,
67 ARG_WRITEPROTECT,
68 ARG_PASSWORD,
69 ARG_RELOADPLUGINS,
70 MAX_ARGS
73 struct WBStartup *WBMsg;
74 #ifndef __AROS__
75 struct Library *IconBase;
76 struct IntuitionBase *IntuitionBase;
77 struct Library *RequesterBase;
78 #endif
80 LONG DoReq (Object *req);
81 void IoErrRequester (LONG error, CONST_STRPTR header);
82 void ErrorStringRequester (CONST_STRPTR error_string);
84 int main (int argc, char **argv) {
85 int rc = RETURN_FAIL;
86 BPTR stderr = ZERO;
87 struct DiskObject *icon = NULL;
88 struct RDArgs *rdargs = NULL;
89 BPTR filedir = ZERO;
90 CONST_STRPTR filename = NULL;
91 CONST_STRPTR drivestr = NULL;
92 LONG unit = -1;
93 BOOL writeprotect = FALSE;
94 CONST_STRPTR password = NULL;
95 CONST_STRPTR plugin = NULL;
96 BOOL eject = FALSE;
97 BOOL reloadplugins = FALSE;
98 LONG error = NO_ERROR;
99 LONG error2 = NO_ERROR;
100 TEXT error_buffer[256];
102 stderr = Output();
104 if (argc == 0) {
105 BPTR currdir;
106 WBMsg = (struct WBStartup *)argv;
107 #ifndef __AROS__
108 if (!(IconBase = OpenLibrary("icon.library", MIN_OS_VERSION)) ||
109 !(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", MIN_OS_VERSION)) ||
110 !(RequesterBase = OpenLibrary("requester.class", MIN_OS_VERSION)))
112 goto error;
114 #endif
115 if (WBMsg->sm_NumArgs < 2) {
116 IoErrRequester(ERROR_REQUIRED_ARG_MISSING, NULL);
117 goto error;
119 filedir = WBMsg->sm_ArgList[1].wa_Lock;
120 filename = WBMsg->sm_ArgList[1].wa_Name;
121 currdir = CurrentDir(filedir);
122 icon = GetDiskObjectNew((STRPTR)filename);
123 CurrentDir(currdir);
124 if (!icon) {
125 IoErrRequester(IoErr(), NULL);
126 goto error;
128 if (!(drivestr = TTString(icon, "DRIVE", NULL)) &&
129 !(drivestr = TTString(icon, "DEVICE", NULL)))
131 drivestr = NULL;
133 unit = TTInteger(icon, "UNIT", unit);
134 writeprotect = TTBoolean(icon, "WP") || TTBoolean(icon, "WRITEPROTECT");
135 if (!(password = TTString(icon, "PWD", NULL)) &&
136 !(password = TTString(icon, "PASSWORD", NULL)))
138 password = NULL;
140 plugin = TTString(icon, "PLUGIN", NULL);
141 } else {
142 IPTR args[MAX_ARGS];
143 ClearMem(args, sizeof(args));
144 rdargs = ReadArgs(TEMPLATE, args, NULL);
145 if (!rdargs) {
146 PrintFault(IoErr(), PROGNAME);
147 goto error;
149 filedir = GetCurrentDir();
150 filename = (CONST_STRPTR)args[ARG_INSERT];
151 eject = args[ARG_EJECT] ? TRUE : FALSE;
152 reloadplugins = args[ARG_RELOADPLUGINS] ? TRUE : FALSE;
153 if (reloadplugins) {
154 unit = -1;
155 } else if (filename || eject) {
156 if (args[ARG_DRIVE]) drivestr = (CONST_STRPTR)args[ARG_DRIVE];
157 if (args[ARG_UNIT]) unit = *(LONG *)args[ARG_UNIT];
158 if (filename) {
159 if (args[ARG_PASSWORD]) password = (CONST_STRPTR)args[ARG_PASSWORD];
160 if (args[ARG_PLUGIN]) plugin = (CONST_STRPTR)args[ARG_PLUGIN];
161 writeprotect = args[ARG_WRITEPROTECT] ? TRUE : FALSE;
163 } else {
164 PrintFault(ERROR_REQUIRED_ARG_MISSING, PROGNAME);
165 goto error;
169 if (drivestr && drivestr[0]) {
170 TEXT drivename[20];
171 LONG len;
172 const ULONG flags = LDF_DEVICES|LDF_READ;
173 struct DosList *dl;
174 BOOL devicefound;
175 TEXT devicename[64];
176 Strlcpy(drivename, drivestr, sizeof(drivename));
177 len = strlen(drivename)-1;
178 if (drivename[len] == ':') {
179 drivename[len] = 0;
181 dl = LockDosList(flags);
182 devicefound = FALSE;
183 if ((dl = FindDosEntry(dl, drivename, flags))) {
184 struct FileSysStartupMsg *fssm;
185 #ifndef __AROS__
186 if (dl->dol_Task) {
187 fssm = (struct FileSysStartupMsg *)DoPkt0(dl->dol_Task, ACTION_GET_DISK_FSSM);
188 if (fssm) {
189 CopyStringBSTRToC(fssm->fssm_Device, devicename, sizeof(devicename));
190 unit = fssm->fssm_Unit;
191 devicefound = TRUE;
192 DoPkt1(dl->dol_Task, ACTION_FREE_DISK_FSSM, (IPTR)fssm);
193 } else if (IoErr() == ERROR_ACTION_NOT_KNOWN) {
194 #endif
195 fssm = CheckBPTR(dl->dol_misc.dol_handler.dol_Startup);
196 if (fssm && CheckBPTR(fssm->fssm_Device)) {
197 CopyStringBSTRToC(fssm->fssm_Device, devicename, sizeof(devicename));
198 unit = fssm->fssm_Unit;
199 devicefound = TRUE;
201 #ifndef __AROS__
204 #endif
206 UnLockDosList(flags);
207 if (!devicefound) {
208 SNPrintf(error_buffer, sizeof(error_buffer), "%s: device not found", drivename);
209 if (WBMsg)
210 ErrorStringRequester(error_buffer);
211 else
212 FPrintf(stderr, "%s\n", error_buffer);
213 goto error;
215 if (strcmp(FilePart(devicename), "diskimage.device")) {
216 SNPrintf(error_buffer, sizeof(error_buffer), "%s: not a diskimage device", drivename);
217 if (WBMsg)
218 ErrorStringRequester(error_buffer);
219 else
220 FPrintf(stderr, "%s\n", error_buffer);
221 goto error;
225 if ((filename || eject) && unit == -1) {
226 if (WBMsg)
227 IoErrRequester(ERROR_REQUIRED_ARG_MISSING, NULL);
228 else
229 PrintFault(ERROR_REQUIRED_ARG_MISSING, PROGNAME);
230 goto error;
233 if (!OpenDiskImageDevice(unit)) {
234 SNPrintf(error_buffer, sizeof(error_buffer),
235 "failed to open diskimage.device");
236 if (WBMsg)
237 ErrorStringRequester(error_buffer);
238 else
239 FPrintf(stderr, "%s: %s\n", PROGNAME, error_buffer);
240 goto error;
243 if (reloadplugins) {
244 error = ReloadPlugins();
245 if (error) {
246 PrintFault(error, PROGNAME);
247 goto error;
249 } else if (filename || eject) {
250 error_buffer[0] = 0;
251 if (filename) {
252 LONG type = DITYPE_NONE;
253 UnitControl(unit,
254 DITAG_DiskImageType, (IPTR)&type,
255 DITAG_Filename, (IPTR)NULL,
256 TAG_END);
257 if (type != DITYPE_NONE) {
258 Delay(5);
260 error = UnitControl(unit,
261 DITAG_Error, (IPTR)&error2,
262 DITAG_ErrorString, (IPTR)error_buffer,
263 DITAG_ErrorStringLength, sizeof(error_buffer),
264 DITAG_Password, (IPTR)password,
265 DITAG_Plugin, (IPTR)plugin,
266 DITAG_CurrentDir, (IPTR)filedir,
267 DITAG_Filename, (IPTR)filename,
268 DITAG_WriteProtect, writeprotect,
269 TAG_END);
270 } else {
271 error = UnitControl(unit,
272 DITAG_Filename, (IPTR)NULL,
273 DITAG_WriteProtect, writeprotect,
274 TAG_END);
276 if (error == NO_ERROR) error = error2;
277 if (error_buffer[0]) {
278 if (WBMsg)
279 ErrorStringRequester(error_buffer);
280 else
281 FPrintf(stderr, "%s: %s\n", filename, error_buffer);
282 goto error;
283 } else if (error) {
284 if (WBMsg)
285 IoErrRequester(error, NULL);
286 else
287 PrintFault(error, filename);
288 goto error;
292 rc = RETURN_OK;
294 error:
295 CloseDiskImageDevice();
296 if (WBMsg) {
297 if (icon) FreeDiskObject(icon);
298 #ifndef __AROS__
299 if (RequesterBase) CloseLibrary(RequesterBase);
300 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
301 if (IconBase) CloseLibrary(IconBase);
302 #endif
303 } else {
304 FreeArgs(rdargs);
307 return rc;
310 #ifdef __AROS__
312 void IoErrRequester (LONG error, CONST_STRPTR header) {
313 TEXT bodytext[80];
314 if (error == NO_ERROR) {
315 return;
317 Fault(error, (STRPTR)header, bodytext, sizeof(bodytext));
318 MUI_Request(NULL, NULL, 0, "Error - "PROGNAME, "Ok", "%s", bodytext);
321 void ErrorStringRequester (CONST_STRPTR error_string) {
322 MUI_Request(NULL, NULL, 0, "Error - "PROGNAME, "Ok", "%s", (STRPTR)error_string);
325 #else
327 LONG DoReq (Object *req) {
328 LONG res = 0;
329 if (req) {
330 res = DoMethod(req, RM_OPENREQ, NULL, NULL, NULL);
331 DisposeObject(req);
333 return res;
336 void IoErrRequester (LONG error, CONST_STRPTR header) {
337 TEXT bodytext[80];
338 Object *req;
339 if (error == NO_ERROR) {
340 return;
342 Fault(error, (STRPTR)header, bodytext, sizeof(bodytext));
343 req = RequesterObject,
344 REQ_TitleText, "Error - "PROGNAME,
345 REQ_BodyText, bodytext,
346 REQ_GadgetText, "_Ok",
347 End;
348 DoReq(req);
351 void ErrorStringRequester (CONST_STRPTR error_string) {
352 Object *req;
353 req = RequesterObject,
354 REQ_TitleText, "Error - "PROGNAME,
355 REQ_BodyText, error_string,
356 REQ_GadgetText, "_Ok",
357 End;
358 DoReq(req);
361 #endif