added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / rom / dos / errorreport.c
blobfa5182b77636680ad28bd1c9b8d47dd13fad21d9
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #include "dos_intern.h"
10 #include <dos/dos.h>
11 #include <dos/dosextens.h>
12 #include <intuition/intuition.h>
13 #include <exec/ports.h>
15 #include <aros/debug.h>
17 /*****************************************************************************
19 NAME */
20 #include <proto/dos.h>
22 AROS_LH4(BOOL, ErrorReport,
24 /* SYNOPSIS */
25 AROS_LHA(LONG , code , D1),
26 AROS_LHA(LONG , type , D2),
27 AROS_LHA(IPTR , arg1 , D3),
28 AROS_LHA(struct MsgPort *, device, D4),
30 /* LOCATION */
31 struct DosLibrary *, DOSBase, 80, Dos)
33 /* FUNCTION
35 INPUTS
37 code -- The error to put up the requester for
38 type -- Type of request
40 REPORT_LOCK -- arg1 is a lock (BPTR).
41 REPORT_FH -- arg1 is a filehandle (BPTR).
42 REPORT_VOLUME -- arg1 is a volumenode (C pointer).
43 REPORT_INSERT -- arg1 is the string for the volumename
45 arg1 -- Argument according to type (see above)
46 device -- Optional handler task address (obsolete!)
48 RESULT
50 NOTES
52 Locks and filehandles are the same in AROS so there is redundancy in
53 the parameters. Furthermore, the 'device' argument is not cared about
54 as AROS doesn't build filesystems with handlers.
56 EXAMPLE
58 BUGS
60 SEE ALSO
62 INTERNALS
64 *****************************************************************************/
66 AROS_LIBFUNC_INIT
68 struct Process *me = (struct Process *) FindTask(NULL);
69 STRPTR format;
70 BOOL want_volume = FALSE;
71 BOOL want_device = FALSE;
72 STRPTR volname = NULL;
73 STRPTR devname = NULL;
74 struct DeviceList *dl = NULL;
75 struct Device *handler = NULL;
76 struct Unit *unit = NULL;
77 char buf[128];
78 struct DevProc *dvp;
79 struct DosList *dol;
80 APTR args[2];
81 ULONG idcmp = 0;
82 LONG err;
83 LONG res;
85 /* do nothing if errors are disabled */
86 if (me->pr_WindowPtr == (APTR) -1) {
87 SetIoErr(err);
88 return DOSTRUE;
91 /* first setup the error format and work out which args we need */
92 switch (code) {
93 /* Volume FOO: is not validated */
94 case ERROR_DISK_NOT_VALIDATED:
95 format = DosGetString(STRING_DISK_NOT_VALIDATED);
96 want_volume = TRUE;
97 break;
99 /* Volume FOO: is write protected */
100 case ERROR_DISK_WRITE_PROTECTED:
101 format = DosGetString(STRING_DISK_WRITE_PROTECTED);
102 want_volume = TRUE;
103 break;
105 /* Please (insert|replace) volume FOO: in ... */
106 case ERROR_DEVICE_NOT_MOUNTED:
107 if (type == REPORT_INSERT) {
108 format = DosGetString(STRING_DEVICE_NOT_MOUNTED_INSERT);
109 want_volume = TRUE;
111 else if (type == REPORT_STREAM) {
112 format = DosGetString(STRING_DEVICE_NOT_MOUNTED_REPLACE_TARGET);
113 want_volume = want_device = TRUE;
115 else {
116 format = DosGetString(STRING_DEVICE_NOT_MOUNTED_REPLACE);
117 want_volume = TRUE;
119 idcmp = IDCMP_DISKINSERTED;
120 break;
122 /* Volume FOO: is full */
123 case ERROR_DISK_FULL:
124 format = DosGetString(STRING_DISK_FULL);
125 want_volume = TRUE;
126 break;
128 /* Not a DOS disk in ...*/
129 case ERROR_NOT_A_DOS_DISK:
130 format = DosGetString(STRING_NOT_A_DOS_DISK);
131 want_device = TRUE;
132 break;
134 /* No disk present in ...*/
135 case ERROR_NO_DISK:
136 format = DosGetString(STRING_NO_DISK);
137 want_device = TRUE;
138 break;
140 /* You MUST replace volume FOO: in ... */
141 case ABORT_BUSY:
142 format = DosGetString(STRING_ABORT_BUSY);
143 want_volume = want_device = TRUE;
144 idcmp = IDCMP_DISKINSERTED;
145 break;
147 /* Volume FOO: has a read/write error */
148 case ABORT_DISK_ERROR:
149 format = DosGetString(STRING_ABORT_DISK_ERROR);
150 want_volume = TRUE;
151 break;
153 /* do nothing with other errors */
154 default:
155 return DOSTRUE;
158 /* now we need to determine the volume name. if they gave it to use
159 * (REPORT_INSERT), we just use it. otherwise, we get it from the device
160 * list (REPORT_VOLUME). if we don't have one, we use the handler/unit
161 * pair to find it */
162 switch (type) {
163 /* a filehandle */
164 case REPORT_STREAM:
165 if (arg1 == NULL)
166 return DOSTRUE;
168 handler = ((struct FileHandle *) BADDR(arg1))->fh_Device;
169 unit = ((struct FileHandle *) BADDR(arg1))->fh_Unit;
170 break;
172 case REPORT_TASK:
173 /* XXX what is this? */
174 return DOSTRUE;
176 /* a lock */
177 case REPORT_LOCK:
178 /* if they provided a lock, just use it */
179 if (arg1 != NULL) {
180 handler = ((struct FileHandle *) BADDR(arg1))->fh_Device;
181 unit = ((struct FileHandle *) BADDR(arg1))->fh_Unit;
184 /* otherwise we use the secondary device, and we look through the
185 * doslist to determine the unit */
186 else {
187 handler = (struct Device *) device;
189 /* find the doslist entry */
190 dol = LockDosList(LDF_READ | LDF_ALL);
191 while (dol != NULL && (dol->dol_Type != DLT_VOLUME ||
192 dol->dol_Ext.dol_AROS.dol_Device != handler))
193 dol = dol->dol_Next;
195 /* found it, steal its unit */
196 if (dol != NULL)
197 unit = dol->dol_Ext.dol_AROS.dol_Unit;
199 UnLockDosList(LDF_READ | LDF_ALL);
201 /* if we didn't find it, there's not much more we can do */
202 if (dol == NULL)
203 return DOSTRUE;
206 break;
208 /* a volume, ie a DeviceList */
209 case REPORT_VOLUME:
210 if (arg1 == NULL)
211 return DOSTRUE;
213 dl = (struct DeviceList *) arg1;
214 break;
216 /* raw volume name */
217 case REPORT_INSERT:
218 if (arg1 == NULL)
219 return DOSTRUE;
221 volname = (STRPTR) arg1;
222 /* rip off any trailing stuff, if its there */
223 if (SplitName(volname, ':', buf, 0, sizeof(buf)-1) == -1)
224 volname = buf;
225 break;
227 /* do nothing with other types */
228 default:
229 return DOSTRUE;
232 /* get the name if we don't already have it */
233 if (volname == NULL) {
235 /* just use the volume pointer if we already have it */
236 if (dl != NULL)
237 volname = dl->dl_Ext.dl_AROS.dol_DevName;
239 /* otherwise we have to get it from the handler */
240 else {
241 /* XXX for packets we'd just call ACTION_CURRENT_DEVICE */
243 struct FileHandle *fh;
244 char *p;
246 /* remember the current error just in case this fails. I don't know if
247 * this is actually necessary but I'm trying to keep side-effects to a
248 * minimum */
249 err = IoErr();
251 /* make a fake lock (filehandle) */
252 if ((fh = AllocDosObject(DOS_FILEHANDLE, 0)) == NULL) {
253 SetIoErr(err);
254 return DOSTRUE;
257 fh->fh_Device = handler;
258 fh->fh_Unit = unit;
260 /* get the handler to give us the name */
261 if (NameFromLock(MKBADDR(fh), buf, 127) != DOSTRUE) {
262 FreeDosObject(fh, DOS_FILEHANDLE);
263 SetIoErr(err);
264 return DOSTRUE;
267 /* cleanup */
268 FreeDosObject(fh, DOS_FILEHANDLE);
269 SetIoErr(err);
271 /* find the volume seperator */
272 for (p = buf; *p != ':' && *p != '\0'; p++);
274 /* not there. can this happen? */
275 if (*p == '\0')
276 return DOSTRUE;
278 /* overwrite it, and we have a volume name */
279 *p = '\0';
281 volname = buf;
285 /* for the device name we need the doslist entry */
286 if (want_device) {
287 /* XXX for packets we just search the doslist for a DLT_DEVICE with
288 * the same task pointer. no need to worry about multiple units */
290 /* remember the current error in case we have to bail out */
291 err = IoErr();
293 /* get the entry for the volume */
294 if ((dvp = GetDeviceProc(volname, NULL)) == NULL) {
295 SetIoErr(err);
296 return DOSTRUE;
299 /* search the list for a device node with the same handler/port as the
300 * volume */
301 dol = LockDosList(LDF_READ | LDF_ALL);
302 while (dol != NULL && (dol->dol_Type != DLT_DEVICE ||
303 dol->dol_Ext.dol_AROS.dol_Device != (struct Device *) dvp->dvp_Port ||
304 dol->dol_Ext.dol_AROS.dol_Unit != dvp->dvp_DevNode->dol_Ext.dol_AROS.dol_Unit))
305 dol = dol->dol_Next;
307 /* found it */
308 if (dol != NULL)
309 devname = dol->dol_Ext.dol_AROS.dol_DevName;
311 /* XXX can this happen? */
312 else
313 devname = "???";
315 UnLockDosList(LDF_READ | LDF_ALL);
317 FreeDeviceProc(dvp);
320 /* have all we need, now to build the arg array */
321 if (want_volume) {
322 args[0] = volname;
323 if (want_device)
324 args[1] = devname;
326 else if (want_device)
327 args[0] = devname;
329 /* display it. idcmp is set further up to catch "disk insert" events if
330 * we're waiting for them to insert something */
332 res = DisplayError(format, idcmp, &args);
334 SetIoErr(code);
336 return res == 0 ? DOSFALSE : DOSTRUE;
338 AROS_LIBFUNC_EXIT
339 } /* ErrorReport */