r25430: Add the loadparm context to all parametric options.
[jelmer/samba4-debian.git] / source / torture / rpc / countcalls.c
index ac4788f349b657cdf042528ac4a5e89da2a81457..eba20e6361ea7a8c14fbeb247248e7f8507bf4da 100644 (file)
@@ -4,10 +4,11 @@
    count number of calls on an interface
 
    Copyright (C) Andrew Tridgell 2003
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007
    
    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/>.
 */
 
 #include "includes.h"
+#include "torture/torture.h"
+#include "librpc/ndr/libndr.h"
+#include "librpc/ndr/ndr_table.h"
+#include "torture/rpc/rpc.h"
+#include "param/param.h"
 
 
-BOOL torture_rpc_countcalls(void)
+       
+BOOL count_calls(TALLOC_CTX *mem_ctx,
+                const struct ndr_interface_table *iface,
+       BOOL all) 
 {
-       const struct dcerpc_interface_table *iface;
-       NTSTATUS status;
        struct dcerpc_pipe *p;
-       int i;
-       const char *iface_name;
        DATA_BLOB stub_in, stub_out;
-       
-       iface_name = lp_parm_string(-1, "countcalls", "interface");
-       if (iface_name == NULL) {
-               printf("You must specify an interface name with countcalls:interface\n");
-               return False;
-       }
-
-       iface = idl_iface_by_name(iface_name);
-       if (!iface) {
-               printf("Unknown interface '%s'\n", iface_name);
-               return False;
-       }
-
-       status = torture_rpc_connection(NULL, &p, iface->endpoints->names[0], 
-                                       iface->uuid, iface->if_version);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("Failed to open '%s' - %s\n", iface->name, nt_errstr(status));
+       int i;
+       NTSTATUS status = torture_rpc_connection(mem_ctx, &p, iface);
+       if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)
+           || NT_STATUS_EQUAL(NT_STATUS_NET_WRITE_FAULT, status)
+           || NT_STATUS_EQUAL(NT_STATUS_PORT_UNREACHABLE, status)
+           || NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) {
+               if (all) {
+                       /* Not fatal if looking for all pipes */
+                       return True;
+               } else {
+                       printf("Failed to open '%s' to count calls - %s\n", iface->name, nt_errstr(status));
+                       return False;
+               }
+       } else if (!NT_STATUS_IS_OK(status)) {
+               printf("Failed to open '%s' to count calls - %s\n", iface->name, nt_errstr(status));
                return False;
        }
 
-       stub_in = data_blob_talloc(p, NULL, 0);
+       stub_in = data_blob_talloc(p, mem_ctx, 0);
 
        printf("\nScanning pipe '%s'\n", iface->name);
 
-       for (i=0;i<5000;i++) {
-               status = dcerpc_request(p, NULL, i, p, &stub_in, &stub_out);
+       for (i=0;i<500;i++) {
+               status = dcerpc_request(p, NULL, i, False, p, &stub_in, &stub_out);
                if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT) &&
-                   p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) break;
+                   p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
+                       i--;
+                       break;
+               }
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT) &&
+                   p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
+                       i--;
+                       break;
+               }
                if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
+                       i--;
+                       break;
+               }
+               if (NT_STATUS_EQUAL(status, NT_STATUS_PIPE_DISCONNECTED)) {
+                       i--;
+                       break;
+               }
+               if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+                       i--;
+                       break;
+               }
+               if (NT_STATUS_EQUAL(status, NT_STATUS_LOGON_FAILURE)) {
+                       i--;
                        break;
                }
        }
        
-       if (i==5000) {
+       if (i==500) {
                talloc_free(p);
-               printf("no limit on calls!?\n");
+               printf("no limit on calls: %s!?\n", nt_errstr(status));
                return False;
        }
 
        printf("Found %d calls\n", i);
 
        talloc_free(p);
-
+       
        return True;
+
+}
+
+BOOL torture_rpc_countcalls(struct torture_context *torture)
+{
+       const struct ndr_interface_table *iface;
+       const char *iface_name;
+       BOOL ret = True;
+       const struct ndr_interface_list *l;
+       TALLOC_CTX *mem_ctx = talloc_named(torture, 0, "torture_rpc_countcalls context");
+       if (!mem_ctx) {
+               return False;
+       }
+       iface_name = lp_parm_string(global_loadparm, NULL, "countcalls", "interface");
+       if (iface_name != NULL) {
+               iface = ndr_table_by_name(iface_name);
+               if (!iface) {
+                       printf("Unknown interface '%s'\n", iface_name);
+                       return False;
+               }
+               return count_calls(mem_ctx, iface, False);
+       }
+
+       for (l=ndr_table_list();l;l=l->next) {          
+               TALLOC_CTX *loop_ctx;
+               loop_ctx = talloc_named(mem_ctx, 0, "torture_rpc_councalls loop context");
+               ret &= count_calls(loop_ctx, l->table, True);
+               talloc_free(loop_ctx);
+       }
+       return ret;
 }