r12608: Remove some unused #include lines.
[abartlet/samba.git/.git] / source4 / libcli / dgram / mailslot.c
index da9b6cdd2007a1668c311d044da209cd0b1a2a4d..0e6b99c3e3b43df1d5ccf40ab2d6c1755f89ef0a 100644 (file)
@@ -1,8 +1,8 @@
 /* 
    Unix SMB/CIFS implementation.
 
-   packet handling for mailslot requests
-
+   packet handling for mailslot requests
+   
    Copyright (C) Andrew Tridgell 2005
    
    This program is free software; you can redistribute it and/or modify
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+/*
+   This implements "Class 2 mailslots", i.e. the communication mechanism 
+   used for all mailslot packets smaller then 425 bytes. 
+
+   "Class 1 mailslots" (which use SMB) are used for messages larger 
+   then 426 bytes and are supported on some systems. These are not implemented
+   in Samba4 yet, as there don't appear to be any core services that use
+   them.
+
+   425 and 426-byte sized messages are not supported at all.
+*/
+
 #include "includes.h"
 #include "lib/events/events.h"
 #include "dlinklist.h"
-#include "libcli/nbt/libnbt.h"
 #include "libcli/dgram/libdgram.h"
 #include "lib/socket/socket.h"
 
@@ -64,6 +75,8 @@ struct dgram_mailslot_handler *dgram_mailslot_listen(struct nbt_dgram_socket *dg
        DLIST_ADD(dgmsock->mailslot_handlers, dgmslot);
        talloc_set_destructor(dgmslot, dgram_mailslot_destructor);
 
+       EVENT_FD_READABLE(dgmsock->fde);
+
        return dgmslot;
 }
 
@@ -95,7 +108,6 @@ const char *dgram_mailslot_name(struct nbt_dgram_packet *packet)
        }
        if (packet->data.msg.dgram_body_type != DGRAM_SMB) return NULL;
        if (packet->data.msg.body.smb.smb_command != SMB_TRANSACTION) return NULL;
-       if (packet->data.msg.body.smb.smb_command != SMB_TRANSACTION) return NULL;
        return packet->data.msg.body.smb.body.trans.mailslot_name;
 }
 
@@ -115,9 +127,9 @@ struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgms
 
        /* try a 100 times at most */
        for (i=0;i<100;i++) {
-               name = talloc_asprintf(dgmsock, "%s%u", 
+               name = talloc_asprintf(dgmsock, "%s%03u", 
                                       mailslot_name,
-                                      generate_random() % UINT16_MAX);
+                                      generate_random() % 1000);
                if (name == NULL) return NULL;
                if (dgram_mailslot_find(dgmsock, name)) {
                        talloc_free(name);
@@ -130,3 +142,83 @@ struct dgram_mailslot_handler *dgram_mailslot_temp(struct nbt_dgram_socket *dgms
        DEBUG(2,("Unable to create temporary mailslot from %s\n", mailslot_name));
        return NULL;
 }
+
+
+/*
+  send a mailslot request
+*/
+NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock,
+                            enum dgram_msg_type msg_type,
+                            const char *mailslot_name,
+                            struct nbt_name *dest_name,
+                            const struct nbt_peer_socket *_dest,
+                            struct nbt_name *src_name,
+                            DATA_BLOB *request)
+{
+       TALLOC_CTX *tmp_ctx = talloc_new(dgmsock);
+       struct nbt_dgram_packet packet;
+       struct nbt_peer_socket dest = *_dest;
+       struct dgram_message *msg;
+       struct dgram_smb_packet *smb;
+       struct smb_trans_body *trans;
+       NTSTATUS status;
+
+       if (dest.port == 0) {
+               dest.port = lp_dgram_port();
+       }
+
+       ZERO_STRUCT(packet);
+       packet.msg_type = msg_type;
+       packet.flags = DGRAM_FLAG_FIRST | DGRAM_NODE_NBDD;
+       packet.dgram_id = generate_random() % UINT16_MAX;
+       packet.src_addr = socket_get_my_addr(dgmsock->sock, tmp_ctx);
+       packet.src_port = socket_get_my_port(dgmsock->sock);
+
+       msg = &packet.data.msg;
+       /* this length calculation is very crude - it should be based on gensize
+          calls */
+       msg->length = 138 + strlen(mailslot_name) + request->length;
+       msg->offset = 0;
+
+       msg->source_name = *src_name;
+       msg->dest_name = *dest_name;
+       msg->dgram_body_type = DGRAM_SMB;
+
+       smb = &msg->body.smb;
+       smb->smb_command = SMB_TRANSACTION;
+
+       trans = &smb->body.trans;
+       trans->total_data_count = request->length;
+       trans->timeout     = 1000;
+       trans->data_count  = request->length;
+       trans->data_offset = 70 + strlen(mailslot_name);
+       trans->opcode      = 1; /* write mail slot */
+       trans->priority    = 1;
+       trans->class       = 2;
+       trans->mailslot_name = mailslot_name;
+       trans->data = *request;
+
+       status = nbt_dgram_send(dgmsock, &packet, &dest);
+
+       talloc_free(tmp_ctx);
+
+       return status;
+}
+
+/*
+  return the mailslot data portion from a mailslot packet
+*/
+DATA_BLOB dgram_mailslot_data(struct nbt_dgram_packet *dgram)
+{
+       struct smb_trans_body *trans = &dgram->data.msg.body.smb.body.trans;
+       DATA_BLOB ret = trans->data;
+       int pad = trans->data_offset - (70 + strlen(trans->mailslot_name));
+
+       if (pad < 0 || pad > ret.length) {
+               DEBUG(2,("Badly formatted data in mailslot - pad = %d\n", pad));
+               return data_blob(NULL, 0);
+       }
+       ret.data += pad;
+       ret.length -= pad;
+       return ret;     
+}