s3: Add "net registry increment"
authorVolker Lendecke <vl@samba.org>
Fri, 12 Mar 2010 14:48:35 +0000 (15:48 +0100)
committerVolker Lendecke <vl@samba.org>
Fri, 12 Mar 2010 15:55:28 +0000 (16:55 +0100)
A convenience function to increment a DWORD value under a (cluster-wide) lock

source3/utils/net_registry.c

index a78d5601db630504bd6a7675a9a49c8b3fae785b..3b55c1406b14c23614a8ecde098677393542dfd3 100644 (file)
@@ -22,6 +22,7 @@
 #include "includes.h"
 #include "utils/net.h"
 #include "utils/net_registry_util.h"
+#include "include/g_lock.h"
 
 
 /*
@@ -385,6 +386,102 @@ done:
        return ret;
 }
 
+struct net_registry_increment_state {
+       const char *keyname;
+       const char *valuename;
+       uint32_t increment;
+       uint32_t newvalue;
+       WERROR werr;
+};
+
+static void net_registry_increment_fn(void *private_data)
+{
+       struct net_registry_increment_state *state =
+               (struct net_registry_increment_state *)private_data;
+       struct registry_value *value;
+       struct registry_key *key = NULL;
+
+       state->werr = open_key(talloc_tos(), state->keyname,
+                              REG_KEY_READ|REG_KEY_WRITE, &key);
+       if (!W_ERROR_IS_OK(state->werr)) {
+               d_fprintf(stderr, _("open_key failed: %s\n"),
+                         win_errstr(state->werr));
+               goto done;
+       }
+
+       state->werr = reg_queryvalue(key, key, state->valuename, &value);
+       if (!W_ERROR_IS_OK(state->werr)) {
+               d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
+                         win_errstr(state->werr));
+               goto done;
+       }
+
+       if (value->type != REG_DWORD) {
+               d_fprintf(stderr, _("value not a DWORD: %s\n"),
+                         reg_type_lookup(value->type));
+               goto done;
+       }
+
+       value->v.dword += state->increment;
+       state->newvalue = value->v.dword;
+
+       state->werr = reg_setvalue(key, state->valuename, value);
+       if (!W_ERROR_IS_OK(state->werr)) {
+               d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
+                         win_errstr(state->werr));
+               goto done;
+       }
+
+done:
+       TALLOC_FREE(key);
+       return;
+}
+
+static int net_registry_increment(struct net_context *c, int argc,
+                                 const char **argv)
+{
+       struct net_registry_increment_state state;
+       NTSTATUS status;
+       int ret = -1;
+
+       if (argc < 2 || c->display_usage) {
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net registry increment <key> <valuename> "
+                           "[<increment>]\n"));
+               goto done;
+       }
+
+       state.keyname = argv[0];
+       state.valuename = argv[1];
+
+       state.increment = 1;
+       if (argc == 3) {
+               state.increment = strtoul(argv[2], NULL, 10);
+       }
+
+       status = g_lock_do("registry_increment_lock", G_LOCK_WRITE,
+                          timeval_set(600, 0),
+                          net_registry_increment_fn, &state);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, _("g_lock_do failed: %s\n"),
+                         nt_errstr(status));
+               goto done;
+       }
+       if (!W_ERROR_IS_OK(state.werr)) {
+               d_fprintf(stderr, _("increment failed: %s\n"),
+                         win_errstr(state.werr));
+               goto done;
+       }
+
+       d_printf(_("%u\n"), (unsigned)state.newvalue);
+
+       ret = 0;
+
+done:
+       return ret;
+}
+
 static int net_registry_deletevalue(struct net_context *c, int argc,
                                    const char **argv)
 {
@@ -668,6 +765,14 @@ int net_registry(struct net_context *c, int argc, const char **argv)
                        N_("net registry setvalue\n"
                           "    Set a new registry value")
                },
+               {
+                       "increment",
+                       net_registry_increment,
+                       NET_TRANSPORT_LOCAL,
+                       N_("Increment a DWORD registry value under a lock"),
+                       N_("net registry increment\n"
+                          "    Increment a DWORD registry value under a lock")
+               },
                {
                        "deletevalue",
                        net_registry_deletevalue,