root/source3/utils/dbwrap_tool.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dbwrap_tool_fetch_int32
  2. dbwrap_tool_fetch_uint32
  3. dbwrap_tool_store_int32
  4. dbwrap_tool_store_uint32
  5. dbwrap_tool_delete
  6. delete_fn
  7. dbwrap_tool_erase
  8. listkey_fn
  9. dbwrap_tool_listkeys
  10. main

   1 /*
   2    Samba Unix/Linux CIFS implementation
   3 
   4    low level TDB/CTDB tool using the dbwrap interface
   5 
   6    Copyright (C) 2009 Michael Adam <obnox@samba.org>
   7 
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12 
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17 
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 
  24 extern bool AllowDebugChange;
  25 
  26 typedef enum { OP_FETCH, OP_STORE, OP_DELETE, OP_ERASE, OP_LISTKEYS } dbwrap_op;
  27 
  28 typedef enum { TYPE_INT32, TYPE_UINT32 } dbwrap_type;
  29 
  30 static int dbwrap_tool_fetch_int32(struct db_context *db,
     /* [<][>][^][v][top][bottom][index][help] */
  31                                    const char *keyname,
  32                                    void *data)
  33 {
  34         int32_t value;
  35 
  36         value = dbwrap_fetch_int32(db, keyname);
  37         d_printf("%d\n", value);
  38 
  39         return 0;
  40 }
  41 
  42 static int dbwrap_tool_fetch_uint32(struct db_context *db,
     /* [<][>][^][v][top][bottom][index][help] */
  43                                     const char *keyname,
  44                                     void *data)
  45 {
  46         uint32_t value;
  47         bool ret;
  48 
  49         ret = dbwrap_fetch_uint32(db, keyname, &value);
  50         if (ret) {
  51                 d_printf("%u\n", value);
  52                 return 0;
  53         } else {
  54                 d_fprintf(stderr, "ERROR: could not fetch uint32 key '%s'\n",
  55                           keyname);
  56                 return -1;
  57         }
  58 }
  59 
  60 static int dbwrap_tool_store_int32(struct db_context *db,
     /* [<][>][^][v][top][bottom][index][help] */
  61                                    const char *keyname,
  62                                    void *data)
  63 {
  64         NTSTATUS status;
  65         int32_t value = *((int32_t *)data);
  66 
  67         status = dbwrap_trans_store_int32(db, keyname, value);
  68 
  69         if (!NT_STATUS_IS_OK(status)) {
  70                 d_fprintf(stderr, "ERROR: could not store int32 key '%s': %s\n",
  71                           keyname, nt_errstr(status));
  72                 return -1;
  73         }
  74 
  75         return 0;
  76 }
  77 
  78 static int dbwrap_tool_store_uint32(struct db_context *db,
     /* [<][>][^][v][top][bottom][index][help] */
  79                                     const char *keyname,
  80                                     void *data)
  81 {
  82         NTSTATUS status;
  83         uint32_t value = *((uint32_t *)data);
  84 
  85         status = dbwrap_trans_store_uint32(db, keyname, value);
  86 
  87         if (!NT_STATUS_IS_OK(status)) {
  88                 d_fprintf(stderr,
  89                           "ERROR: could not store uint32 key '%s': %s\n",
  90                           keyname, nt_errstr(status));
  91                 return -1;
  92         }
  93 
  94         return 0;
  95 }
  96 
  97 static int dbwrap_tool_delete(struct db_context *db,
     /* [<][>][^][v][top][bottom][index][help] */
  98                               const char *keyname,
  99                               void *data)
 100 {
 101         NTSTATUS status;
 102 
 103         status = dbwrap_trans_delete_bystring(db, keyname);
 104 
 105         if (!NT_STATUS_IS_OK(status)) {
 106                 d_fprintf(stderr, "ERROR deleting record %s : %s\n",
 107                           keyname, nt_errstr(status));
 108                 return -1;
 109         }
 110 
 111         return 0;
 112 }
 113 
 114 static int delete_fn(struct db_record *rec, void *priv)
     /* [<][>][^][v][top][bottom][index][help] */
 115 {
 116         rec->delete_rec(rec);
 117         return 0;
 118 }
 119 
 120 /**
 121  * dbwrap_tool_erase: erase the whole data base
 122  * the keyname argument is not used.
 123  */
 124 static int dbwrap_tool_erase(struct db_context *db,
     /* [<][>][^][v][top][bottom][index][help] */
 125                              const char *keyname,
 126                              void *data)
 127 {
 128         int ret;
 129 
 130         ret = db->traverse(db, delete_fn, NULL);
 131 
 132         if (ret < 0) {
 133                 d_fprintf(stderr, "ERROR erasing the database\n");
 134                 return -1;
 135         }
 136 
 137         return 0;
 138 }
 139 
 140 static int listkey_fn(struct db_record *rec, void *private_data)
     /* [<][>][^][v][top][bottom][index][help] */
 141 {
 142         int length = rec->key.dsize;
 143         unsigned char *p = (unsigned char *)rec->key.dptr;
 144 
 145         while (length--) {
 146                 if (isprint(*p) && !strchr("\"\\", *p)) {
 147                         d_printf("%c", *p);
 148                 } else {
 149                         d_printf("\\%02X", *p);
 150                 }
 151                 p++;
 152         }
 153 
 154         d_printf("\n");
 155 
 156         return 0;
 157 }
 158 
 159 static int dbwrap_tool_listkeys(struct db_context *db,
     /* [<][>][^][v][top][bottom][index][help] */
 160                                 const char *keyname,
 161                                 void *data)
 162 {
 163         int ret;
 164 
 165         ret = db->traverse_read(db, listkey_fn, NULL);
 166 
 167         if (ret < 0) {
 168                 d_fprintf(stderr, "ERROR listing db keys\n");
 169                 return -1;
 170         }
 171 
 172         return 0;
 173 }
 174 
 175 struct dbwrap_op_dispatch_table {
 176         dbwrap_op op;
 177         dbwrap_type type;
 178         int (*cmd)(struct db_context *db,
 179                    const char *keyname,
 180                    void *data);
 181 };
 182 
 183 struct dbwrap_op_dispatch_table dispatch_table[] = {
 184         { OP_FETCH,  TYPE_INT32,  dbwrap_tool_fetch_int32 },
 185         { OP_FETCH,  TYPE_UINT32, dbwrap_tool_fetch_uint32 },
 186         { OP_STORE,  TYPE_INT32,  dbwrap_tool_store_int32 },
 187         { OP_STORE,  TYPE_UINT32, dbwrap_tool_store_uint32 },
 188         { OP_DELETE, TYPE_INT32,  dbwrap_tool_delete },
 189         { OP_ERASE,  TYPE_INT32,  dbwrap_tool_erase },
 190         { OP_LISTKEYS, TYPE_INT32, dbwrap_tool_listkeys },
 191         { 0, 0, NULL },
 192 };
 193 
 194 int main(int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 195 {
 196         struct tevent_context *evt_ctx;
 197         struct messaging_context *msg_ctx;
 198         struct db_context *db;
 199 
 200         uint16_t count;
 201 
 202         const char *dbname;
 203         const char *opname;
 204         dbwrap_op op;
 205         const char *keyname = "";
 206         const char *keytype = "int32";
 207         dbwrap_type type;
 208         const char *valuestr = "0";
 209         int32_t value = 0;
 210 
 211         TALLOC_CTX *mem_ctx = talloc_stackframe();
 212 
 213         int ret = 1;
 214 
 215         load_case_tables();
 216         DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
 217         dbf = x_stderr;
 218         AllowDebugChange = false;
 219         lp_load(get_dyn_CONFIGFILE(), true, false, false, true);
 220 
 221         if ((argc < 3) || (argc > 6)) {
 222                 d_fprintf(stderr,
 223                           "USAGE: %s <database> <op> [<key> [<type> [<value>]]]\n"
 224                           "       ops: fetch, store, delete, erase, listkeys\n"
 225                           "       types: int32, uint32\n",
 226                          argv[0]);
 227                 goto done;
 228         }
 229 
 230         dbname = argv[1];
 231         opname = argv[2];
 232 
 233         if (strcmp(opname, "store") == 0) {
 234                 if (argc != 6) {
 235                         d_fprintf(stderr, "ERROR: operation 'store' requires "
 236                                   "value argument\n");
 237                         goto done;
 238                 }
 239                 valuestr = argv[5];
 240                 keytype = argv[4];
 241                 keyname = argv[3];
 242                 op = OP_STORE;
 243         } else if (strcmp(opname, "fetch") == 0) {
 244                 if (argc != 5) {
 245                         d_fprintf(stderr, "ERROR: operation 'fetch' requires "
 246                                   "type but not value argument\n");
 247                         goto done;
 248                 }
 249                 op = OP_FETCH;
 250                 keytype = argv[4];
 251                 keyname = argv[3];
 252         } else if (strcmp(opname, "delete") == 0) {
 253                 if (argc != 4) {
 254                         d_fprintf(stderr, "ERROR: operation 'delete' does "
 255                                   "not allow type nor value argument\n");
 256                         goto done;
 257                 }
 258                 keyname = argv[3];
 259                 op = OP_DELETE;
 260         } else if (strcmp(opname, "erase") == 0) {
 261                 if (argc != 3) {
 262                         d_fprintf(stderr, "ERROR: operation 'erase' does "
 263                                   "not take a key argument\n");
 264                         goto done;
 265                 }
 266                 op = OP_ERASE;
 267         } else if (strcmp(opname, "listkeys") == 0) {
 268                 if (argc != 3) {
 269                         d_fprintf(stderr, "ERROR: operation 'listkeys' does "
 270                                   "not take a key argument\n");
 271                         goto done;
 272                 }
 273                 op = OP_LISTKEYS;
 274         } else {
 275                 d_fprintf(stderr,
 276                           "ERROR: invalid op '%s' specified\n"
 277                           "       supported ops: fetch, store, delete\n",
 278                           opname);
 279                 goto done;
 280         }
 281 
 282         if (strcmp(keytype, "int32") == 0) {
 283                 type = TYPE_INT32;
 284                 value = (int32_t)strtol(valuestr, NULL, 10);
 285         } else if (strcmp(keytype, "uint32") == 0) {
 286                 type = TYPE_UINT32;
 287                 value = (int32_t)strtoul(valuestr, NULL, 10);
 288         } else {
 289                 d_fprintf(stderr, "ERROR: invalid type '%s' specified.\n"
 290                                   "       supported types: int32, uint32\n",
 291                                   keytype);
 292                 goto done;
 293         }
 294 
 295         evt_ctx = tevent_context_init(mem_ctx);
 296         if (evt_ctx == NULL) {
 297                 d_fprintf(stderr, "ERROR: could not init event context\n");
 298                 goto done;
 299         }
 300 
 301         msg_ctx = messaging_init(mem_ctx, server_id_self(), evt_ctx);
 302         if (msg_ctx == NULL) {
 303                 d_fprintf(stderr, "ERROR: could not init messaging context\n");
 304                 goto done;
 305         }
 306 
 307         db = db_open(mem_ctx, dbname, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
 308         if (db == NULL) {
 309                 d_fprintf(stderr, "ERROR: could not open dbname\n");
 310                 goto done;
 311         }
 312 
 313         for (count = 0; dispatch_table[count].cmd != NULL; count++) {
 314                 if ((op == dispatch_table[count].op) &&
 315                     (type == dispatch_table[count].type))
 316                 {
 317                         ret = dispatch_table[count].cmd(db, keyname, &value);
 318                         break;
 319                 }
 320         }
 321 
 322 done:
 323         TALLOC_FREE(mem_ctx);
 324         return ret;
 325 }

/* [<][>][^][v][top][bottom][index][help] */