Detabbed
[AROS.git] / rom / dos / startnotify.c
blobe7d89c35efe74e758f5b85973e421fb36a1ffa6d
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #include <dos/notify.h>
10 #include <dos/exall.h>
11 #include <proto/dos.h>
12 #include <aros/debug.h>
13 #include <string.h>
15 #include "dos_intern.h"
17 /*****************************************************************************
19 NAME */
21 AROS_LH1(BOOL, StartNotify,
23 /* SYNOPSIS */
24 AROS_LHA(struct NotifyRequest *, notify, D1),
26 /* LOCATION */
27 struct DosLibrary *, DOSBase, 148, Dos)
29 /* FUNCTION
31 Send a notification request to a filesystem. You will then be notified
32 whenever the file (or directory) changes.
34 INPUTS
36 notify -- a notification request for the file or directory to monitor
38 RESULT
40 Success/failure indicator.
42 NOTES
44 The file or directory connected to a notification request does not have
45 to exist at the time of calling StartNotify().
46 The NotifyRequest used with this function should not be altered while
47 active.
49 EXAMPLE
51 BUGS
53 SEE ALSO
55 EndNotify(), <dos/notify.h>
57 INTERNALS
59 *****************************************************************************/
61 AROS_LIBFUNC_INIT
63 LONG err;
64 struct DevProc *dvp;
65 UBYTE buf[MAXFILENAMELENGTH+1], *buf2, *p;
66 ULONG len, len2;
67 BPTR lock = BNULL;
69 /* set up some defaults */
70 notify->nr_MsgCount = 0;
71 notify->nr_FullName = NULL;
73 D(bug("[StartNotify] Request 0x%p, Name %s\n", notify, notify->nr_Name));
75 /* turn the filename into a device and dir lock */
76 if ((dvp = GetDeviceProc(notify->nr_Name, NULL)) == NULL)
77 return DOSFALSE;
79 /* remember the handler for EndNotify() */
80 notify->nr_Handler = dvp->dvp_Port;
82 /* if no lock is returned by GetDeviceProc() (eg if the path is for a
83 * device or volume root), then get the handler to resolve the name of the
84 * device root lock */
85 if (dvp->dvp_Lock == BNULL)
87 UBYTE name[MAXFILENAMELENGTH+1], *src, *dst;
88 struct FileInfoBlock *fib;
90 src = notify->nr_Name;
91 dst = name;
93 while (*src != ':')
94 *dst++ = *src++;
96 *dst++ = ':';
97 *dst++ = '\0';
99 if ((fib = AllocDosObject(DOS_FIB, NULL)) == NULL) {
100 FreeDeviceProc(dvp);
101 return DOSFALSE;
104 if((lock = Lock(name, SHARED_LOCK)) == BNULL) {
105 FreeDosObject(DOS_FIB, fib);
106 FreeDeviceProc(dvp);
107 return DOSFALSE;
110 if (!Examine(lock, fib)) {
111 FreeDosObject(DOS_FIB, fib);
112 FreeDeviceProc(dvp);
113 return DOSFALSE;
116 /* copy it to our processing buffer */
117 src = fib->fib_FileName;
118 dst = buf;
120 while (*src != '\0')
121 *dst++ = *src++;
123 *dst++ = ':';
124 *dst++ = '\0';
126 FreeDosObject(DOS_FIB, fib);
129 /* otherwise we need to expand the name using the lock */
130 else
132 /* get the name */
133 if (NameFromLock(dvp->dvp_Lock, buf, sizeof(buf)) == DOSFALSE)
135 FreeDeviceProc(dvp);
136 return DOSFALSE;
140 len = strlen(buf);
142 /* if it's not some absolute base thing, then add a dir seperator for
143 * the concat operation below */
144 if (buf[len-1] != ':') {
145 buf[len] = '/';
146 len++;
149 /* look for the ':' following the assign name in the path provided by
150 * the caller */
151 p = notify->nr_Name;
152 while (*p && *p != ':')
153 p++;
155 /* if we found it, move past it */
156 if (*p)
157 p++;
159 /* hit the end, so the name is a relative path, and we take all of it */
160 else
161 p = notify->nr_Name;
163 len2 = strlen(p);
165 if ((buf2 = AllocVec(len + len2 + 1, MEMF_PUBLIC)) == NULL)
167 SetIoErr(ERROR_NO_FREE_STORE);
169 /* cleanup */
170 if (lock != BNULL)
171 UnLock(lock);
172 FreeDeviceProc(dvp);
174 return DOSFALSE;
177 /* concatenate the two bits */
178 CopyMem(buf, buf2, len);
179 CopyMem(p, buf2 + len, len2 + 1);
181 /* that's our expanded name */
182 notify->nr_FullName = buf2;
184 /* send the request, with error reporting */
187 err = fs_AddNotify(notify, dvp, lock, DOSBase);
188 } while (err != 0 && ErrorReport(err, REPORT_LOCK, 0, notify->nr_Handler) == DOSFALSE);
190 /* cleanup */
191 if (lock != BNULL)
192 UnLock(lock);
193 FreeDeviceProc(dvp);
195 /* something broke, clean up */
196 if (err != 0)
198 if (notify->nr_FullName != notify->nr_Name)
200 FreeVec(notify->nr_FullName);
201 notify->nr_FullName = NULL;
204 SetIoErr(err);
205 return DOSFALSE;
208 D(bug("[StartNotify] nr_Handler 0x%p\n", notify->nr_Handler));
210 return DOSTRUE;
212 AROS_LIBFUNC_EXIT
213 } /* StartNotify */