/* start listening on a mailslot. talloc_free() the handle to stop listening */ struct dgram_mailslot_handler *dgram_mailslot_listen(struct nbt_dgram_socket *dgmsock, const char *mailslot_name, dgram_mailslot_handler_t handler, void *private_data) { struct dgram_mailslot_handler *dgmslot; dgmslot = talloc(dgmsock, struct dgram_mailslot_handler); if (dgmslot == NULL) return NULL; dgmslot->dgmsock = dgmsock; dgmslot->mailslot_name = talloc_strdup(dgmslot, mailslot_name); if (dgmslot->mailslot_name == NULL) { talloc_free(dgmslot); return NULL; } dgmslot->handler = handler; dgmslot->private_data = private_data; DLIST_ADD(dgmsock->mailslot_handlers, dgmslot); talloc_set_destructor(dgmslot, dgram_mailslot_destructor); EVENT_FD_READABLE(dgmsock->fde); return dgmslot; }
/* setup a handler for generic incoming requests */ NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, struct socket_address *), void *private_data) { dgmsock->incoming.handler = handler; dgmsock->incoming.private_data = private_data; EVENT_FD_READABLE(dgmsock->fde); return NT_STATUS_OK; }
/* handle send events on a nbt name socket */ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) { struct nbt_name_request *req = nbtsock->send_queue; TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); NTSTATUS status; while ((req = nbtsock->send_queue)) { size_t len; len = req->encoded.length; status = socket_sendto(nbtsock->sock, &req->encoded, &len, req->dest); if (NT_STATUS_IS_ERR(status)) goto failed; if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } DLIST_REMOVE(nbtsock->send_queue, req); req->state = NBT_REQUEST_WAIT; if (req->is_reply) { talloc_free(req); } else { EVENT_FD_READABLE(nbtsock->fde); nbtsock->num_pending++; } } EVENT_FD_NOT_WRITEABLE(nbtsock->fde); talloc_free(tmp_ctx); return; failed: DLIST_REMOVE(nbtsock->send_queue, req); nbt_name_request_destructor(req); req->status = status; req->state = NBT_REQUEST_ERROR; talloc_free(tmp_ctx); if (req->async.fn) { req->async.fn(req); } return; }