s4:ntvfs: fix O3 error unused result of asprintf
[amitay/samba.git] / source4 / ntvfs / ntvfs_util.c
index 929ec037de182cb26d17ba435bc923bf07d4364a..116313925522f88b302323dba6cfe8b30973c14c 100644 (file)
@@ -5,7 +5,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 /*
   this implements common utility functions that many NTVFS backends may wish to use
 */
 
 #include "includes.h"
+#include "../lib/util/dlinklist.h"
+#include "ntvfs/ntvfs.h"
 
-NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req,
-                               void *private_data,
-                               void (*send_fn)(struct smbsrv_request *),
-                               struct ntvfs_module_context *ntvfs)
+
+struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, TALLOC_CTX *mem_ctx,
+                                                   struct auth_session_info *session_info,
+                                                   uint16_t smbpid,
+                                                   struct timeval request_time,
+                                                   void *private_data,
+                                                   void (*send_fn)(struct ntvfs_request *),
+                                                   uint32_t state)
 {
+       struct ntvfs_request *req;
        struct ntvfs_async_state *async;
 
-       async = talloc_p(req, struct ntvfs_async_state);
-       if (!async) {
-               return NT_STATUS_NO_MEMORY;
-       }
+       req = talloc(mem_ctx, struct ntvfs_request);
+       if (!req) return NULL;
+       req->ctx                        = ctx;
+       req->async_states               = NULL;
+       req->session_info               = session_info;
+       req->smbpid                     = smbpid;
+       req->client_caps                = ctx->client_caps;
+       req->statistics.request_time    = request_time;
+
+       async = talloc(req, struct ntvfs_async_state);
+       if (!async) goto failed;
+
+       async->state            = state;
+       async->private_data     = private_data;
+       async->send_fn          = send_fn;
+       async->status           = NT_STATUS_INTERNAL_ERROR;
+       async->ntvfs            = NULL;
+
+       DLIST_ADD(req->async_states, async);
+
+       return req;
+failed:
+       talloc_free(req);
+       return NULL;
+}
+
+NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs,
+                                        struct ntvfs_request *req,
+                                        void *private_data,
+                                        void (*send_fn)(struct ntvfs_request *))
+{
+       struct ntvfs_async_state *async;
+
+       async = talloc(req, struct ntvfs_async_state);
+       NT_STATUS_HAVE_NO_MEMORY(async);
 
        async->state            = req->async_states->state;
        async->private_data     = private_data;
@@ -47,7 +84,7 @@ NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req,
        return NT_STATUS_OK;
 }
 
-void ntvfs_async_state_pop(struct smbsrv_request *req)
+void ntvfs_async_state_pop(struct ntvfs_request *req)
 {
        struct ntvfs_async_state *async;
 
@@ -60,3 +97,106 @@ void ntvfs_async_state_pop(struct smbsrv_request *req)
 
        talloc_free(async);
 }
+
+NTSTATUS ntvfs_handle_new(struct ntvfs_module_context *ntvfs,
+                                  struct ntvfs_request *req,
+                                  struct ntvfs_handle **h)
+{
+       if (!ntvfs->ctx->handles.create_new) {
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+       return ntvfs->ctx->handles.create_new(ntvfs->ctx->handles.private_data, req, h);
+}
+
+NTSTATUS ntvfs_handle_set_backend_data(struct ntvfs_handle *h,
+                                               struct ntvfs_module_context *ntvfs,
+                                               TALLOC_CTX *private_data)
+{
+       struct ntvfs_handle_data *d;
+       bool first_time = h->backend_data?false:true;
+
+       for (d=h->backend_data; d; d = d->next) {
+               if (d->owner != ntvfs) continue;
+               d->private_data = talloc_steal(d, private_data);
+               return NT_STATUS_OK;
+       }
+
+       d = talloc(h, struct ntvfs_handle_data);
+       NT_STATUS_HAVE_NO_MEMORY(d);
+       d->owner = ntvfs;
+       d->private_data = talloc_steal(d, private_data);
+
+       DLIST_ADD(h->backend_data, d);
+
+       if (first_time) {
+               NTSTATUS status;
+               status = h->ctx->handles.make_valid(h->ctx->handles.private_data, h);
+               NT_STATUS_NOT_OK_RETURN(status);
+       }
+
+       return NT_STATUS_OK;
+}
+
+void *ntvfs_handle_get_backend_data(struct ntvfs_handle *h,
+                                            struct ntvfs_module_context *ntvfs)
+{
+       struct ntvfs_handle_data *d;
+
+       for (d=h->backend_data; d; d = d->next) {
+               if (d->owner != ntvfs) continue;
+               return d->private_data;
+       }
+
+       return NULL;
+}
+
+void ntvfs_handle_remove_backend_data(struct ntvfs_handle *h,
+                                              struct ntvfs_module_context *ntvfs)
+{
+       struct ntvfs_handle_data *d,*n;
+
+       for (d=h->backend_data; d; d = n) {
+               n = d->next;
+               if (d->owner != ntvfs) continue;
+               DLIST_REMOVE(h->backend_data, d);
+               talloc_free(d);
+               d = NULL;
+       }
+
+       if (h->backend_data) return;
+
+       /* if there's no backend_data anymore, destroy the handle */
+       h->ctx->handles.destroy(h->ctx->handles.private_data, h);
+}
+
+struct ntvfs_handle *ntvfs_handle_search_by_wire_key(struct ntvfs_module_context *ntvfs,
+                                                             struct ntvfs_request *req,
+                                                             const DATA_BLOB *key)
+{
+       if (!ntvfs->ctx->handles.search_by_wire_key) {
+               return NULL;
+       }
+       return ntvfs->ctx->handles.search_by_wire_key(ntvfs->ctx->handles.private_data, req, key);
+}
+
+DATA_BLOB ntvfs_handle_get_wire_key(struct ntvfs_handle *h, TALLOC_CTX *mem_ctx)
+{
+       return h->ctx->handles.get_wire_key(h->ctx->handles.private_data, h, mem_ctx);
+}
+
+NTSTATUS ntvfs_set_handle_callbacks(struct ntvfs_context *ntvfs,
+                                            NTSTATUS (*create_new)(void *private_data, struct ntvfs_request *req, struct ntvfs_handle **h),
+                                            NTSTATUS (*make_valid)(void *private_data, struct ntvfs_handle *h),
+                                            void (*destroy)(void *private_data, struct ntvfs_handle *h),
+                                            struct ntvfs_handle *(*search_by_wire_key)(void *private_data, struct ntvfs_request *req, const DATA_BLOB *key),
+                                            DATA_BLOB (*get_wire_key)(void *private_data, struct ntvfs_handle *handle, TALLOC_CTX *mem_ctx),
+                                            void *private_data)
+{
+       ntvfs->handles.create_new               = create_new;
+       ntvfs->handles.make_valid               = make_valid;
+       ntvfs->handles.destroy                  = destroy;
+       ntvfs->handles.search_by_wire_key       = search_by_wire_key;
+       ntvfs->handles.get_wire_key             = get_wire_key;
+       ntvfs->handles.private_data             = private_data;
+       return NT_STATUS_OK;
+}