smbd: There's only one notify_callback
[kai/samba-autobuild/.git] / source3 / smbd / notify.c
index e776749a318778ec5528135c6a927270fde645ac..f493f11aa69a558389689b2fe3fc271b297adf32 100644 (file)
@@ -138,6 +138,7 @@ static bool notify_marshall_changes(int num_changes,
                struct notify_change_event *c;
                struct FILE_NOTIFY_INFORMATION m;
                DATA_BLOB blob;
+               uint16_t pad = 0;
 
                /* Coalesce any identical records. */
                while (i+1 < num_changes &&
@@ -151,12 +152,23 @@ static bool notify_marshall_changes(int num_changes,
                m.FileName1 = c->name;
                m.FileNameLength = strlen_m(c->name)*2;
                m.Action = c->action;
-               m.NextEntryOffset = (i == num_changes-1) ? 0 : ndr_size_FILE_NOTIFY_INFORMATION(&m, 0);
+
+               m._pad = data_blob_null;
 
                /*
                 * Offset to next entry, only if there is one
                 */
 
+               if (i == (num_changes-1)) {
+                       m.NextEntryOffset = 0;
+               } else {
+                       if ((m.FileNameLength % 4) == 2) {
+                               m._pad = data_blob_const(&pad, 2);
+                       }
+                       m.NextEntryOffset =
+                               ndr_size_FILE_NOTIFY_INFORMATION(&m, 0);
+               }
+
                ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &m,
                        (ndr_push_flags_fn_t)ndr_push_FILE_NOTIFY_INFORMATION);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -228,8 +240,8 @@ void change_notify_reply(struct smb_request *req,
        notify_buf->num_changes = 0;
 }
 
-static void notify_callback(void *private_data, struct timespec when,
-                           const struct notify_event *e)
+void notify_callback(void *private_data, struct timespec when,
+                    const struct notify_event *e)
 {
        files_struct *fsp = (files_struct *)private_data;
        DEBUG(10, ("notify_callback called for %s\n", fsp_str_dbg(fsp)));
@@ -239,8 +251,8 @@ static void notify_callback(void *private_data, struct timespec when,
 NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
                              bool recursive)
 {
-       char *fullpath;
-       size_t len;
+       size_t len = fsp_fullbasepath(fsp, NULL, 0);
+       char fullpath[len+1];
        uint32_t subdir_filter;
        NTSTATUS status = NT_STATUS_NOT_IMPLEMENTED;
 
@@ -255,20 +267,11 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
                return NT_STATUS_NO_MEMORY;
        }
 
-       /* Do notify operations on the base_name. */
-       fullpath = talloc_asprintf(
-               talloc_tos(), "%s/%s", fsp->conn->connectpath,
-               fsp->fsp_name->base_name);
-       if (fullpath == NULL) {
-               DEBUG(0, ("talloc_asprintf failed\n"));
-               TALLOC_FREE(fsp->notify);
-               return NT_STATUS_NO_MEMORY;
-       }
+       fsp_fullbasepath(fsp, fullpath, sizeof(fullpath));
 
        /*
         * Avoid /. at the end of the path name. notify can't deal with it.
         */
-       len = strlen(fullpath);
        if (len > 1 && fullpath[len-1] == '.' && fullpath[len-2] == '/') {
                fullpath[len-2] = '\0';
        }
@@ -277,10 +280,9 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter,
 
        if ((filter != 0) || (subdir_filter != 0)) {
                status = notify_add(fsp->conn->sconn->notify_ctx,
-                                   fullpath, filter, subdir_filter,
-                                   notify_callback, fsp);
+                                   fullpath, filter, subdir_filter, fsp);
        }
-       TALLOC_FREE(fullpath);
+
        return status;
 }
 
@@ -315,8 +317,7 @@ NTSTATUS change_notify_add_request(struct smb_request *req,
        request->reply_fn = reply_fn;
        request->backend_data = NULL;
 
-       DLIST_ADD_END(fsp->notify->requests, request,
-                     struct notify_change_request *);
+       DLIST_ADD_END(fsp->notify->requests, request);
 
        map->mid = request->req->mid;
        DLIST_ADD(sconn->smb1.notify_mid_maps, map);