Use read_packet for wb_req_read
authorVolker Lendecke <vl@samba.org>
Sun, 22 Feb 2009 23:06:56 +0000 (00:06 +0100)
committerVolker Lendecke <vl@samba.org>
Tue, 24 Feb 2009 19:40:48 +0000 (20:40 +0100)
source3/lib/wb_reqtrans.c

index 1be7239..76b0f53 100644 (file)
@@ -27,9 +27,7 @@
 
 struct req_read_state {
        struct winbindd_request *wb_req;
-       struct tevent_context *ev;
        size_t max_extra_data;
-       int fd;
 };
 
 bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err)
@@ -83,145 +81,91 @@ wbcErr async_req_simple_recv_wbcerr(struct async_req *req)
        return WBC_ERR_SUCCESS;
 }
 
-static void wb_req_read_len(struct async_req *subreq);
-static void wb_req_read_main(struct async_req *subreq);
-static void wb_req_read_extra(struct async_req *subreq);
+static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data);
+static void wb_req_read_done(struct tevent_req *subreq);
 
 struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
                                   struct tevent_context *ev,
                                   int fd, size_t max_extra_data)
 {
-       struct async_req *result, *subreq;
+       struct async_req *result;
+       struct tevent_req *subreq;
        struct req_read_state *state;
 
        if (!async_req_setup(mem_ctx, &result, &state,
                             struct req_read_state)) {
                return NULL;
        }
-       state->fd = fd;
-       state->ev = ev;
        state->max_extra_data = max_extra_data;
-       state->wb_req = talloc(state, struct winbindd_request);
-       if (state->wb_req == NULL) {
-               goto nomem;
-       }
 
-       subreq = recvall_send(state, ev, state->fd, &(state->wb_req->length),
-                             sizeof(state->wb_req->length), 0);
+       subreq = read_packet_send(state, ev, fd, 4, wb_req_more, state);
        if (subreq == NULL) {
                goto nomem;
        }
 
-       subreq->async.fn = wb_req_read_len;
-       subreq->async.priv = result;
+       subreq->async.fn = wb_req_read_done;
+       subreq->async.private_data = result;
        return result;
-
  nomem:
        TALLOC_FREE(result);
        return NULL;
 }
 
-static void wb_req_read_len(struct async_req *subreq)
+static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data)
 {
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
        struct req_read_state *state = talloc_get_type_abort(
-               req->private_data, struct req_read_state);
-       int err;
-       ssize_t ret;
+               private_data, struct req_read_state);
+       struct winbindd_request *req = (struct winbindd_request *)buf;
 
-       ret = recvall_recv(subreq, &err);
-       TALLOC_FREE(subreq);
-       if (ret < 0) {
-               async_req_error(req, map_wbc_err_from_errno(err));
-               return;
+       if (buflen == 4) {
+               if (req->length != sizeof(struct winbindd_request)) {
+                       DEBUG(0, ("wb_req_read_len: Invalid request size "
+                                 "received: %d (expected %d)\n",
+                                 (int)req->length,
+                                 (int)sizeof(struct winbindd_request)));
+                       return -1;
+               }
+               return sizeof(struct winbindd_request) - 4;
        }
 
-       if (state->wb_req->length != sizeof(struct winbindd_request)) {
-               DEBUG(0, ("wb_req_read_len: Invalid request size received: "
-                         "%d (expected %d)\n", (int)state->wb_req->length,
-                         (int)sizeof(struct winbindd_request)));
-               async_req_error(req, WBC_ERR_INVALID_RESPONSE);
-               return;
-       }
-
-       subreq = recvall_send(
-               req, state->ev, state->fd, (uint32 *)(state->wb_req)+1,
-               sizeof(struct winbindd_request) - sizeof(uint32), 0);
-       if (async_req_nomem(subreq, req)) {
-               return;
+       if ((state->max_extra_data != 0)
+           && (req->extra_len > state->max_extra_data)) {
+               DEBUG(3, ("Got request with %d bytes extra data on "
+                         "unprivileged socket\n", (int)req->extra_len));
+               return -1;
        }
 
-       subreq->async.fn = wb_req_read_main;
-       subreq->async.priv = req;
+       return req->extra_len;
 }
 
-static void wb_req_read_main(struct async_req *subreq)
+static void wb_req_read_done(struct tevent_req *subreq)
 {
        struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
+               subreq->async.private_data, struct async_req);
        struct req_read_state *state = talloc_get_type_abort(
                req->private_data, struct req_read_state);
        int err;
        ssize_t ret;
+       uint8_t *buf;
 
-       ret = recvall_recv(subreq, &err);
+       ret = read_packet_recv(subreq, state, &buf, &err);
        TALLOC_FREE(subreq);
-       if (ret < 0) {
+       if (ret == -1) {
                async_req_error(req, map_wbc_err_from_errno(err));
                return;
        }
 
-       if ((state->max_extra_data != 0)
-           && (state->wb_req->extra_len > state->max_extra_data)) {
-               DEBUG(3, ("Got request with %d bytes extra data on "
-                         "unprivileged socket\n",
-                         (int)state->wb_req->extra_len));
-               async_req_error(req, WBC_ERR_INVALID_RESPONSE);
-               return;
-       }
-
-       if (state->wb_req->extra_len == 0) {
-               async_req_done(req);
-               return;
-       }
-
-       state->wb_req->extra_data.data = TALLOC_ARRAY(
-               state->wb_req, char, state->wb_req->extra_len + 1);
-       if (async_req_nomem(state->wb_req->extra_data.data, req)) {
-               return;
-       }
-
-       state->wb_req->extra_data.data[state->wb_req->extra_len] = 0;
-
-       subreq = recvall_send(
-               req, state->ev, state->fd, state->wb_req->extra_data.data,
-               state->wb_req->extra_len, 0);
-       if (async_req_nomem(subreq, req)) {
-               return;
-       }
-
-       subreq->async.fn = wb_req_read_extra;
-       subreq->async.priv = req;
-}
+       state->wb_req = (struct winbindd_request *)buf;
 
-static void wb_req_read_extra(struct async_req *subreq)
-{
-       struct async_req *req = talloc_get_type_abort(
-               subreq->async.priv, struct async_req);
-       int err;
-       ssize_t ret;
-
-       ret = recvall_recv(subreq, &err);
-       TALLOC_FREE(subreq);
-       if (ret < 0) {
-               async_req_error(req, map_wbc_err_from_errno(err));
-               return;
+       if (state->wb_req->extra_len != 0) {
+               state->wb_req->extra_data.data =
+                       (char *)buf + sizeof(struct winbindd_request);
+       } else {
+               state->wb_req->extra_data.data = NULL;
        }
        async_req_done(req);
 }
 
-
 wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
                        struct winbindd_request **preq)
 {