Add new strings.
[AROS.git] / rom / dos / startnotify.c
blob63f5c54f115c684a8c989dc480eccea8385b25fc
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
8 #include <dos/notify.h>
9 #include <dos/exall.h>
10 #include <proto/dos.h>
11 #include "dos_intern.h"
12 #include <aros/debug.h>
13 #include <string.h>
15 /*****************************************************************************
17 NAME */
19 AROS_LH1(BOOL, StartNotify,
21 /* SYNOPSIS */
22 AROS_LHA(struct NotifyRequest *, notify, D1),
24 /* LOCATION */
25 struct DosLibrary *, DOSBase, 148, Dos)
27 /* FUNCTION
29 Send a notification request to a filesystem. You will then be notified
30 whenever the file (or directory) changes.
32 INPUTS
34 notify -- a notification request for the file or directory to monitor
36 RESULT
38 Success/failure indicator.
40 NOTES
42 The file or directory connected to a notification request does not have
43 to exist at the time of calling StartNotify().
44 The NotifyRequest used with this function should not be altered while
45 active.
47 EXAMPLE
49 BUGS
51 SEE ALSO
53 EndNotify(), <dos/notify.h>
55 INTERNALS
57 *****************************************************************************/
59 AROS_LIBFUNC_INIT
61 struct IOFileSys iofs;
62 struct DevProc *dvp;
63 UBYTE buf[MAXFILENAMELENGTH+1], *buf2, *p;
64 ULONG len, len2;
65 BPTR lock = NULL;
67 /* set up some defaults */
68 notify->nr_MsgCount = 0;
69 notify->nr_FullName = NULL;
71 /* turn the filename into a device and dir lock */
72 if ((dvp = GetDeviceProc(notify->nr_Name, NULL)) == NULL)
73 return DOSFALSE;
75 /* prepare the notify request */
76 InitIOFS(&iofs, FSA_ADD_NOTIFY, DOSBase);
77 iofs.io_Union.io_NOTIFY.io_NotificationRequest = notify;
78 iofs.IOFS.io_Device = (struct Device *) dvp->dvp_Port;
80 /* remember the handler for EndNotify() (but see the comments there about
81 * why we don't really use it */
82 notify->nr_Handler = dvp->dvp_Port;
84 /* if no lock is returned by GetDeviceProc() (eg if the path is for a
85 * device or volume root), then get the handler to resolve the name of the
86 * device root lock */
87 if (dvp->dvp_Lock == NULL) {
88 UBYTE name[MAXFILENAMELENGTH+1], *src, *dst;
89 struct FileInfoBlock *fib;
91 src = notify->nr_Name;
92 dst = name;
94 while (*src != ':')
95 *dst++ = *src++;
97 *dst++ = ':';
98 *dst++ = '\0';
100 if ((fib = AllocDosObject(DOS_FIB, NULL)) == NULL) {
101 FreeDeviceProc(dvp);
102 return DOSFALSE;
105 if((lock = Lock(name, SHARED_LOCK)) == NULL) {
106 FreeDosObject(DOS_FIB, fib);
107 FreeDeviceProc(dvp);
108 return DOSFALSE;
111 if (!Examine(lock, fib)) {
112 FreeDosObject(DOS_FIB, fib);
113 FreeDeviceProc(dvp);
114 return DOSFALSE;
117 /* copy it to our processing buffer */
118 src = fib->fib_FileName;
119 dst = buf;
121 while (*src != '\0')
122 *dst++ = *src++;
124 *dst++ = ':';
125 *dst++ = '\0';
127 /* use the root lock we just got as the relative lock */
128 iofs.IOFS.io_Unit = ((struct FileHandle *) BADDR(lock))->fh_Unit;
130 FreeDosObject(DOS_FIB, fib);
133 /* otherwise we need to expand the name using the lock */
134 else {
135 /* get the name */
136 if (NameFromLock(dvp->dvp_Lock, buf, sizeof(buf)) == DOSFALSE) {
137 FreeDeviceProc(dvp);
138 return DOSFALSE;
141 /* use the assign base lock as the relative lock */
142 iofs.IOFS.io_Unit = ((struct FileHandle *) BADDR(dvp->dvp_Lock))->fh_Unit;
145 len = strlen(buf);
147 /* if its not some absolute base thing, then add a dir seperator for
148 * the concat operation below */
149 if (buf[len-1] != ':') {
150 buf[len] = '/';
151 len++;
154 /* look for the ':' following the assign name in the path provided by
155 * the caller */
156 p = notify->nr_Name;
157 while (*p && *p != ':')
158 p++;
160 /* if we found it, move past it */
161 if (*p)
162 p++;
164 /* hit the end, so the name is a relative path, and we take all of it */
165 else
166 p = notify->nr_Name;
168 len2 = strlen(p);
170 if ((buf2 = AllocVec(len + len2 + 1, MEMF_PUBLIC)) == NULL) {
171 SetIoErr(ERROR_NO_FREE_STORE);
173 /* cleanup */
174 if (lock != NULL)
175 UnLock(lock);
176 FreeDeviceProc(dvp);
178 return DOSFALSE;
181 /* concatenate the two bits */
182 CopyMem(buf, buf2, len);
183 CopyMem(p, buf2 + len, len2 + 1);
185 /* thats our expanded name */
186 notify->nr_FullName = buf2;
188 /* send the request, with error reporting */
189 do {
190 DosDoIO(&iofs.IOFS);
191 } while (iofs.io_DosError != 0 && ErrorReport(iofs.io_DosError, REPORT_LOCK, 0, dvp->dvp_Port) == DOSFALSE);
193 SetIoErr(iofs.io_DosError);
195 /* cleanup */
196 if (lock != NULL)
197 UnLock(lock);
198 FreeDeviceProc(dvp);
200 /* something broke, clean up */
201 if (iofs.io_DosError != 0) {
202 if (notify->nr_FullName != notify->nr_Name)
203 FreeVec(notify->nr_FullName);
204 return DOSFALSE;
207 return DOSTRUE;
209 AROS_LIBFUNC_EXIT
210 } /* StartNotify */