root/source3/lib/dbwrap_util.c

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

DEFINITIONS

This source file includes following definitions.
  1. dbwrap_fetch_int32
  2. dbwrap_store_int32
  3. dbwrap_fetch_uint32
  4. dbwrap_store_uint32
  5. dbwrap_change_uint32_atomic
  6. dbwrap_change_int32_atomic
  7. dbwrap_trans_store
  8. dbwrap_trans_delete
  9. dbwrap_trans_store_int32
  10. dbwrap_trans_store_uint32
  11. dbwrap_trans_store_bystring
  12. dbwrap_trans_delete_bystring

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    Utility functions for the dbwrap API
   4    Copyright (C) Volker Lendecke 2007
   5    
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 2 of the License, or
   9    (at your option) any later version.
  10    
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15    
  16    You should have received a copy of the GNU General Public License
  17    along with this program; if not, write to the Free Software
  18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 */
  20 
  21 #include "includes.h"
  22 
  23 int32_t dbwrap_fetch_int32(struct db_context *db, const char *keystr)
     /* [<][>][^][v][top][bottom][index][help] */
  24 {
  25         TDB_DATA dbuf;
  26         int32 ret;
  27 
  28         if (db->fetch(db, NULL, string_term_tdb_data(keystr), &dbuf) != 0) {
  29                 return -1;
  30         }
  31 
  32         if ((dbuf.dptr == NULL) || (dbuf.dsize != sizeof(int32_t))) {
  33                 TALLOC_FREE(dbuf.dptr);
  34                 return -1;
  35         }
  36 
  37         ret = IVAL(dbuf.dptr, 0);
  38         TALLOC_FREE(dbuf.dptr);
  39         return ret;
  40 }
  41 
  42 int dbwrap_store_int32(struct db_context *db, const char *keystr, int32_t v)
     /* [<][>][^][v][top][bottom][index][help] */
  43 {
  44         struct db_record *rec;
  45         int32 v_store;
  46         NTSTATUS status;
  47 
  48         rec = db->fetch_locked(db, NULL, string_term_tdb_data(keystr));
  49         if (rec == NULL) {
  50                 return -1;
  51         }
  52 
  53         SIVAL(&v_store, 0, v);
  54 
  55         status = rec->store(rec, make_tdb_data((const uint8 *)&v_store,
  56                                                sizeof(v_store)),
  57                             TDB_REPLACE);
  58         TALLOC_FREE(rec);
  59         return NT_STATUS_IS_OK(status) ? 0 : -1;
  60 }
  61 
  62 bool dbwrap_fetch_uint32(struct db_context *db, const char *keystr,
     /* [<][>][^][v][top][bottom][index][help] */
  63                          uint32_t *val)
  64 {
  65         TDB_DATA dbuf;
  66 
  67         if (db->fetch(db, NULL, string_term_tdb_data(keystr), &dbuf) != 0) {
  68                 return false;
  69         }
  70 
  71         if ((dbuf.dptr == NULL) || (dbuf.dsize != sizeof(uint32_t))) {
  72                 TALLOC_FREE(dbuf.dptr);
  73                 return false;
  74         }
  75 
  76         *val = IVAL(dbuf.dptr, 0);
  77         TALLOC_FREE(dbuf.dptr);
  78         return true;
  79 }
  80 
  81 int dbwrap_store_uint32(struct db_context *db, const char *keystr, uint32_t v)
     /* [<][>][^][v][top][bottom][index][help] */
  82 {
  83         struct db_record *rec;
  84         uint32 v_store;
  85         NTSTATUS status;
  86 
  87         rec = db->fetch_locked(db, NULL, string_term_tdb_data(keystr));
  88         if (rec == NULL) {
  89                 return -1;
  90         }
  91 
  92         SIVAL(&v_store, 0, v);
  93 
  94         status = rec->store(rec, make_tdb_data((const uint8 *)&v_store,
  95                                                sizeof(v_store)),
  96                             TDB_REPLACE);
  97         TALLOC_FREE(rec);
  98         return NT_STATUS_IS_OK(status) ? 0 : -1;
  99 }
 100 
 101 /**
 102  * Atomic unsigned integer change (addition):
 103  *
 104  * if value does not exist yet in the db, use *oldval as initial old value.
 105  * return old value in *oldval.
 106  * store *oldval + change_val to db.
 107  */
 108 uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr,
     /* [<][>][^][v][top][bottom][index][help] */
 109                                      uint32_t *oldval, uint32_t change_val)
 110 {
 111         struct db_record *rec;
 112         uint32 val = -1;
 113         TDB_DATA data;
 114 
 115         if (!(rec = db->fetch_locked(db, NULL,
 116                                      string_term_tdb_data(keystr)))) {
 117                 return -1;
 118         }
 119 
 120         if (rec->value.dptr == NULL) {
 121                 val = *oldval;
 122         } else if (rec->value.dsize == sizeof(val)) {
 123                 val = IVAL(rec->value.dptr, 0);
 124                 *oldval = val;
 125         } else {
 126                 return -1;
 127         }
 128 
 129         val += change_val;
 130 
 131         data.dsize = sizeof(val);
 132         data.dptr = (uint8 *)&val;
 133 
 134         rec->store(rec, data, TDB_REPLACE);
 135 
 136         TALLOC_FREE(rec);
 137 
 138         return 0;
 139 }
 140 
 141 /**
 142  * Atomic integer change (addition):
 143  *
 144  * if value does not exist yet in the db, use *oldval as initial old value.
 145  * return old value in *oldval.
 146  * store *oldval + change_val to db.
 147  */
 148 int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr,
     /* [<][>][^][v][top][bottom][index][help] */
 149                                  int32 *oldval, int32 change_val)
 150 {
 151         struct db_record *rec;
 152         int32 val = -1;
 153         TDB_DATA data;
 154 
 155         if (!(rec = db->fetch_locked(db, NULL,
 156                                      string_term_tdb_data(keystr)))) {
 157                 return -1;
 158         }
 159 
 160         if (rec->value.dptr == NULL) {
 161                 val = *oldval;
 162         } else if (rec->value.dsize == sizeof(val)) {
 163                 val = IVAL(rec->value.dptr, 0);
 164                 *oldval = val;
 165         } else {
 166                 return -1;
 167         }
 168 
 169         val += change_val;
 170 
 171         data.dsize = sizeof(val);
 172         data.dptr = (uint8 *)&val;
 173 
 174         rec->store(rec, data, TDB_REPLACE);
 175 
 176         TALLOC_FREE(rec);
 177 
 178         return 0;
 179 }
 180 
 181 NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf,
     /* [<][>][^][v][top][bottom][index][help] */
 182                             int flag)
 183 {
 184         int res;
 185         struct db_record *rec = NULL;
 186         NTSTATUS status;
 187 
 188         res = db->transaction_start(db);
 189         if (res != 0) {
 190                 DEBUG(5, ("transaction_start failed\n"));
 191                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
 192         }
 193 
 194         rec = db->fetch_locked(db, talloc_tos(), key);
 195         if (rec == NULL) {
 196                 DEBUG(5, ("fetch_locked failed\n"));
 197                 status = NT_STATUS_NO_MEMORY;
 198                 goto cancel;
 199         }
 200 
 201         status = rec->store(rec, dbuf, flag);
 202         if (!NT_STATUS_IS_OK(status)) {
 203                 DEBUG(5, ("store returned %s\n", nt_errstr(status)));
 204                 goto cancel;
 205         }
 206 
 207         TALLOC_FREE(rec);
 208 
 209         res = db->transaction_commit(db);
 210         if (res != 0) {
 211                 DEBUG(5, ("tdb_transaction_commit failed\n"));
 212                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
 213                 TALLOC_FREE(rec);
 214                 return status;
 215         }
 216 
 217         return NT_STATUS_OK;
 218 
 219  cancel:
 220         TALLOC_FREE(rec);
 221 
 222         if (db->transaction_cancel(db) != 0) {
 223                 smb_panic("Cancelling transaction failed");
 224         }
 225         return status;
 226 }
 227 
 228 NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key)
     /* [<][>][^][v][top][bottom][index][help] */
 229 {
 230         int res;
 231         struct db_record *rec = NULL;
 232         NTSTATUS status;
 233 
 234         res = db->transaction_start(db);
 235         if (res != 0) {
 236                 DEBUG(5, ("transaction_start failed\n"));
 237                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
 238         }
 239 
 240         rec = db->fetch_locked(db, talloc_tos(), key);
 241         if (rec == NULL) {
 242                 DEBUG(5, ("fetch_locked failed\n"));
 243                 status = NT_STATUS_NO_MEMORY;
 244                 goto cancel;
 245         }
 246 
 247         status = rec->delete_rec(rec);
 248         if (!NT_STATUS_IS_OK(status)) {
 249                 DEBUG(5, ("delete_rec returned %s\n", nt_errstr(status)));
 250                 goto cancel;
 251         }
 252 
 253         TALLOC_FREE(rec);
 254 
 255         res = db->transaction_commit(db);
 256         if (res != 0) {
 257                 DEBUG(5, ("tdb_transaction_commit failed\n"));
 258                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
 259                 TALLOC_FREE(rec);
 260                 return status;          
 261         }
 262 
 263         return NT_STATUS_OK;
 264 
 265  cancel:
 266         TALLOC_FREE(rec);
 267 
 268         if (db->transaction_cancel(db) != 0) {
 269                 smb_panic("Cancelling transaction failed");
 270         }
 271         return status;
 272 }
 273 
 274 NTSTATUS dbwrap_trans_store_int32(struct db_context *db, const char *keystr,
     /* [<][>][^][v][top][bottom][index][help] */
 275                                   int32_t v)
 276 {
 277         int32 v_store;
 278 
 279         SIVAL(&v_store, 0, v);
 280 
 281         return dbwrap_trans_store(db, string_term_tdb_data(keystr),
 282                                   make_tdb_data((const uint8 *)&v_store,
 283                                                 sizeof(v_store)),
 284                                   TDB_REPLACE);
 285 }
 286 
 287 NTSTATUS dbwrap_trans_store_uint32(struct db_context *db, const char *keystr,
     /* [<][>][^][v][top][bottom][index][help] */
 288                                    uint32_t v)
 289 {
 290         uint32 v_store;
 291 
 292         SIVAL(&v_store, 0, v);
 293 
 294         return dbwrap_trans_store(db, string_term_tdb_data(keystr),
 295                                   make_tdb_data((const uint8 *)&v_store,
 296                                                 sizeof(v_store)),
 297                                   TDB_REPLACE);
 298 }
 299 
 300 NTSTATUS dbwrap_trans_store_bystring(struct db_context *db, const char *key,
     /* [<][>][^][v][top][bottom][index][help] */
 301                                      TDB_DATA data, int flags)
 302 {
 303         return dbwrap_trans_store(db, string_term_tdb_data(key), data, flags);
 304 }
 305 
 306 NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key)
     /* [<][>][^][v][top][bottom][index][help] */
 307 {
 308         return dbwrap_trans_delete(db, string_term_tdb_data(key));
 309 }

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