root/lib/smbconf/smbconf_txt.c

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

DEFINITIONS

This source file includes following definitions.
  1. pd
  2. smbconf_txt_do_section
  3. smbconf_txt_do_parameter
  4. smbconf_txt_flush_cache
  5. smbconf_txt_init_cache
  6. smbconf_txt_load_file
  7. smbconf_txt_init
  8. smbconf_txt_shutdown
  9. smbconf_txt_requires_messaging
  10. smbconf_txt_is_writeable
  11. smbconf_txt_open
  12. smbconf_txt_close
  13. smbconf_txt_get_csn
  14. smbconf_txt_drop
  15. smbconf_txt_get_share_names
  16. smbconf_txt_share_exists
  17. smbconf_txt_create_share
  18. smbconf_txt_get_share
  19. smbconf_txt_delete_share
  20. smbconf_txt_set_parameter
  21. smbconf_txt_get_parameter
  22. smbconf_txt_delete_parameter
  23. smbconf_txt_get_includes
  24. smbconf_txt_set_includes
  25. smbconf_txt_delete_includes
  26. smbconf_txt_transaction_start
  27. smbconf_txt_transaction_commit
  28. smbconf_txt_transaction_cancel
  29. smbconf_init_txt

   1 /*
   2  *  Unix SMB/CIFS implementation.
   3  *  libsmbconf - Samba configuration library, text backend
   4  *  Copyright (C) Michael Adam 2008
   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 3 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, see <http://www.gnu.org/licenses/>.
  18  */
  19 
  20 /*
  21  * This is a sample implementation of a libsmbconf text backend
  22  * using the params.c parser.
  23  *
  24  * It is read only.
  25  * Don't expect brilliant performance, since it is not hashing the lists.
  26  */
  27 
  28 #include "includes.h"
  29 #include "smbconf_private.h"
  30 
  31 struct txt_cache {
  32         uint32_t current_share;
  33         uint32_t num_shares;
  34         char **share_names;
  35         uint32_t *num_params;
  36         char ***param_names;
  37         char ***param_values;
  38 };
  39 
  40 struct txt_private_data {
  41         struct txt_cache *cache;
  42         uint64_t csn;
  43         bool verbatim;
  44 };
  45 
  46 /**********************************************************************
  47  *
  48  * helper functions
  49  *
  50  **********************************************************************/
  51 
  52 /**
  53  * a convenience helper to cast the private data structure
  54  */
  55 static struct txt_private_data *pd(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  56 {
  57         return (struct txt_private_data *)(ctx->data);
  58 }
  59 
  60 static bool smbconf_txt_do_section(const char *section, void *private_data)
     /* [<][>][^][v][top][bottom][index][help] */
  61 {
  62         WERROR werr;
  63         uint32_t idx;
  64         struct txt_private_data *tpd = (struct txt_private_data *)private_data;
  65         struct txt_cache *cache = tpd->cache;
  66 
  67         if (smbconf_find_in_array(section, cache->share_names,
  68                                   cache->num_shares, &idx))
  69         {
  70                 cache->current_share = idx;
  71                 return true;
  72         }
  73 
  74         werr = smbconf_add_string_to_array(cache, &(cache->share_names),
  75                                            cache->num_shares, section);
  76         if (!W_ERROR_IS_OK(werr)) {
  77                 return false;
  78         }
  79         cache->current_share = cache->num_shares;
  80         cache->num_shares++;
  81 
  82         cache->param_names = talloc_realloc(cache,
  83                                                   cache->param_names,
  84                                                   char **,
  85                                                   cache->num_shares);
  86         if (cache->param_names == NULL) {
  87                 return false;
  88         }
  89         cache->param_names[cache->current_share] = NULL;
  90 
  91         cache->param_values = talloc_realloc(cache,
  92                                                    cache->param_values,
  93                                                    char **,
  94                                                    cache->num_shares);
  95         if (cache->param_values == NULL) {
  96                 return false;
  97         }
  98         cache->param_values[cache->current_share] = NULL;
  99 
 100         cache->num_params = talloc_realloc(cache,
 101                                                  cache->num_params,
 102                                                  uint32_t,
 103                                                  cache->num_shares);
 104         if (cache->num_params == NULL) {
 105                 return false;
 106         }
 107         cache->num_params[cache->current_share] = 0;
 108 
 109         return true;
 110 }
 111 
 112 static bool smbconf_txt_do_parameter(const char *param_name,
     /* [<][>][^][v][top][bottom][index][help] */
 113                                      const char *param_value,
 114                                      void *private_data)
 115 {
 116         WERROR werr;
 117         char **param_names, **param_values;
 118         uint32_t num_params;
 119         uint32_t idx;
 120         struct txt_private_data *tpd = (struct txt_private_data *)private_data;
 121         struct txt_cache *cache = tpd->cache;
 122 
 123         if (cache->num_shares == 0) {
 124                 /*
 125                  * not in any share yet,
 126                  * initialize the "empty" section (NULL):
 127                  * parameters without a previous [section] are stored here.
 128                  */
 129                 if (!smbconf_txt_do_section(NULL, private_data)) {
 130                         return false;
 131                 }
 132         }
 133 
 134         param_names  = cache->param_names[cache->current_share];
 135         param_values = cache->param_values[cache->current_share];
 136         num_params   = cache->num_params[cache->current_share];
 137 
 138         if (!(tpd->verbatim) &&
 139             smbconf_find_in_array(param_name, param_names, num_params, &idx))
 140         {
 141                 talloc_free(param_values[idx]);
 142                 param_values[idx] = talloc_strdup(cache, param_value);
 143                 if (param_values[idx] == NULL) {
 144                         return false;
 145                 }
 146                 return true;
 147         }
 148         werr = smbconf_add_string_to_array(cache,
 149                                 &(cache->param_names[cache->current_share]),
 150                                 num_params, param_name);
 151         if (!W_ERROR_IS_OK(werr)) {
 152                 return false;
 153         }
 154         werr = smbconf_add_string_to_array(cache,
 155                                 &(cache->param_values[cache->current_share]),
 156                                 num_params, param_value);
 157         cache->num_params[cache->current_share]++;
 158         return W_ERROR_IS_OK(werr);
 159 }
 160 
 161 static void smbconf_txt_flush_cache(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 162 {
 163         talloc_free(pd(ctx)->cache);
 164         pd(ctx)->cache = NULL;
 165 }
 166 
 167 static WERROR smbconf_txt_init_cache(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 168 {
 169         if (pd(ctx)->cache != NULL) {
 170                 smbconf_txt_flush_cache(ctx);
 171         }
 172 
 173         pd(ctx)->cache = talloc_zero(pd(ctx), struct txt_cache);
 174 
 175         if (pd(ctx)->cache == NULL) {
 176                 return WERR_NOMEM;
 177         }
 178 
 179         return WERR_OK;
 180 }
 181 
 182 static WERROR smbconf_txt_load_file(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 183 {
 184         WERROR werr;
 185         uint64_t new_csn;
 186 
 187         if (!file_exist(ctx->path)) {
 188                 return WERR_BADFILE;
 189         }
 190 
 191         new_csn = (uint64_t)file_modtime(ctx->path);
 192         if (new_csn == pd(ctx)->csn) {
 193                 return WERR_OK;
 194         }
 195 
 196         werr = smbconf_txt_init_cache(ctx);
 197         if (!W_ERROR_IS_OK(werr)) {
 198                 return werr;
 199         }
 200 
 201         if (!pm_process(ctx->path, smbconf_txt_do_section,
 202                         smbconf_txt_do_parameter, pd(ctx)))
 203         {
 204                 return WERR_CAN_NOT_COMPLETE;
 205         }
 206 
 207         pd(ctx)->csn = new_csn;
 208 
 209         return WERR_OK;
 210 }
 211 
 212 
 213 /**********************************************************************
 214  *
 215  * smbconf operations: text backend implementations
 216  *
 217  **********************************************************************/
 218 
 219 /**
 220  * initialize the text based smbconf backend
 221  */
 222 static WERROR smbconf_txt_init(struct smbconf_ctx *ctx, const char *path)
     /* [<][>][^][v][top][bottom][index][help] */
 223 {
 224         if (path == NULL) {
 225                 return WERR_BADFILE;
 226         }
 227         ctx->path = talloc_strdup(ctx, path);
 228         if (ctx->path == NULL) {
 229                 return WERR_NOMEM;
 230         }
 231 
 232         ctx->data = talloc_zero(ctx, struct txt_private_data);
 233         if (ctx->data == NULL) {
 234                 return WERR_NOMEM;
 235         }
 236 
 237         pd(ctx)->verbatim = true;
 238 
 239         return WERR_OK;
 240 }
 241 
 242 static int smbconf_txt_shutdown(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 243 {
 244         return ctx->ops->close_conf(ctx);
 245 }
 246 
 247 static bool smbconf_txt_requires_messaging(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 248 {
 249         return false;
 250 }
 251 
 252 static bool smbconf_txt_is_writeable(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 253 {
 254         /* no write support in this backend yet... */
 255         return false;
 256 }
 257 
 258 static WERROR smbconf_txt_open(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 259 {
 260         return smbconf_txt_load_file(ctx);
 261 }
 262 
 263 static int smbconf_txt_close(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 264 {
 265         smbconf_txt_flush_cache(ctx);
 266         return 0;
 267 }
 268 
 269 /**
 270  * Get the change sequence number of the given service/parameter.
 271  * service and parameter strings may be NULL.
 272  */
 273 static void smbconf_txt_get_csn(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 274                                 struct smbconf_csn *csn,
 275                                 const char *service, const char *param)
 276 {
 277         if (csn == NULL) {
 278                 return;
 279         }
 280 
 281         csn->csn = (uint64_t)file_modtime(ctx->path);
 282 }
 283 
 284 /**
 285  * Drop the whole configuration (restarting empty)
 286  */
 287 static WERROR smbconf_txt_drop(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 288 {
 289         return WERR_NOT_SUPPORTED;
 290 }
 291 
 292 /**
 293  * get the list of share names defined in the configuration.
 294  */
 295 static WERROR smbconf_txt_get_share_names(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 296                                           TALLOC_CTX *mem_ctx,
 297                                           uint32_t *num_shares,
 298                                           char ***share_names)
 299 {
 300         uint32_t count;
 301         uint32_t added_count = 0;
 302         TALLOC_CTX *tmp_ctx = NULL;
 303         WERROR werr = WERR_OK;
 304         char **tmp_share_names = NULL;
 305 
 306         if ((num_shares == NULL) || (share_names == NULL)) {
 307                 werr = WERR_INVALID_PARAM;
 308                 goto done;
 309         }
 310 
 311         werr = smbconf_txt_load_file(ctx);
 312         if (!W_ERROR_IS_OK(werr)) {
 313                 return werr;
 314         }
 315 
 316         tmp_ctx = talloc_stackframe();
 317 
 318         /* make sure "global" is always listed first,
 319          * possibly after NULL section */
 320 
 321         if (smbconf_share_exists(ctx, NULL)) {
 322                 werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
 323                                                    0, NULL);
 324                 if (!W_ERROR_IS_OK(werr)) {
 325                         goto done;
 326                 }
 327                 added_count++;
 328         }
 329 
 330         if (smbconf_share_exists(ctx, GLOBAL_NAME)) {
 331                 werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
 332                                                    added_count, GLOBAL_NAME);
 333                 if (!W_ERROR_IS_OK(werr)) {
 334                         goto done;
 335                 }
 336                 added_count++;
 337         }
 338 
 339         for (count = 0; count < pd(ctx)->cache->num_shares; count++) {
 340                 if (strequal(pd(ctx)->cache->share_names[count], GLOBAL_NAME) ||
 341                     (pd(ctx)->cache->share_names[count] == NULL))
 342                 {
 343                         continue;
 344                 }
 345 
 346                 werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
 347                                         added_count,
 348                                         pd(ctx)->cache->share_names[count]);
 349                 if (!W_ERROR_IS_OK(werr)) {
 350                         goto done;
 351                 }
 352                 added_count++;
 353         }
 354 
 355         *num_shares = added_count;
 356         if (added_count > 0) {
 357                 *share_names = talloc_move(mem_ctx, &tmp_share_names);
 358         } else {
 359                 *share_names = NULL;
 360         }
 361 
 362 done:
 363         talloc_free(tmp_ctx);
 364         return werr;
 365 }
 366 
 367 /**
 368  * check if a share/service of a given name exists
 369  */
 370 static bool smbconf_txt_share_exists(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 371                                      const char *servicename)
 372 {
 373         WERROR werr;
 374 
 375         werr = smbconf_txt_load_file(ctx);
 376         if (!W_ERROR_IS_OK(werr)) {
 377                 return false;
 378         }
 379 
 380         return smbconf_find_in_array(servicename,
 381                                      pd(ctx)->cache->share_names,
 382                                      pd(ctx)->cache->num_shares, NULL);
 383 }
 384 
 385 /**
 386  * Add a service if it does not already exist
 387  */
 388 static WERROR smbconf_txt_create_share(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 389                                        const char *servicename)
 390 {
 391         return WERR_NOT_SUPPORTED;
 392 }
 393 
 394 /**
 395  * get a definition of a share (service) from configuration.
 396  */
 397 static WERROR smbconf_txt_get_share(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 398                                     TALLOC_CTX *mem_ctx,
 399                                     const char *servicename,
 400                                     struct smbconf_service **service)
 401 {
 402         WERROR werr;
 403         uint32_t sidx, count;
 404         bool found;
 405         TALLOC_CTX *tmp_ctx = NULL;
 406         struct smbconf_service *tmp_service = NULL;
 407 
 408         werr = smbconf_txt_load_file(ctx);
 409         if (!W_ERROR_IS_OK(werr)) {
 410                 return werr;
 411         }
 412 
 413         found = smbconf_find_in_array(servicename,
 414                                       pd(ctx)->cache->share_names,
 415                                       pd(ctx)->cache->num_shares,
 416                                       &sidx);
 417         if (!found) {
 418                 return WERR_NO_SUCH_SERVICE;
 419         }
 420 
 421         tmp_ctx = talloc_stackframe();
 422 
 423         tmp_service = talloc_zero(tmp_ctx, struct smbconf_service);
 424         if (tmp_service == NULL) {
 425                 werr = WERR_NOMEM;
 426                 goto done;
 427         }
 428 
 429         if (servicename != NULL) {
 430                 tmp_service->name = talloc_strdup(tmp_service, servicename);
 431                 if (tmp_service->name == NULL) {
 432                         werr = WERR_NOMEM;
 433                         goto done;
 434                 }
 435         }
 436 
 437         for (count = 0; count < pd(ctx)->cache->num_params[sidx]; count++) {
 438                 werr = smbconf_add_string_to_array(tmp_service,
 439                                 &(tmp_service->param_names),
 440                                 count,
 441                                 pd(ctx)->cache->param_names[sidx][count]);
 442                 if (!W_ERROR_IS_OK(werr)) {
 443                         goto done;
 444                 }
 445                 werr = smbconf_add_string_to_array(tmp_service,
 446                                 &(tmp_service->param_values),
 447                                 count,
 448                                 pd(ctx)->cache->param_values[sidx][count]);
 449                 if (!W_ERROR_IS_OK(werr)) {
 450                         goto done;
 451                 }
 452         }
 453 
 454         tmp_service->num_params = count;
 455         if (count > 0) {
 456                 *service = talloc_move(mem_ctx, &tmp_service);
 457         } else {
 458                 *service = NULL;
 459         }
 460 
 461 done:
 462         talloc_free(tmp_ctx);
 463         return werr;
 464 }
 465 
 466 /**
 467  * delete a service from configuration
 468  */
 469 static WERROR smbconf_txt_delete_share(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 470                                        const char *servicename)
 471 {
 472         return WERR_NOT_SUPPORTED;
 473 }
 474 
 475 /**
 476  * set a configuration parameter to the value provided.
 477  */
 478 static WERROR smbconf_txt_set_parameter(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 479                                         const char *service,
 480                                         const char *param,
 481                                         const char *valstr)
 482 {
 483         return WERR_NOT_SUPPORTED;
 484 }
 485 
 486 /**
 487  * get the value of a configuration parameter as a string
 488  */
 489 static WERROR smbconf_txt_get_parameter(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 490                                         TALLOC_CTX *mem_ctx,
 491                                         const char *service,
 492                                         const char *param,
 493                                         char **valstr)
 494 {
 495         WERROR werr;
 496         bool found;
 497         uint32_t share_index, param_index;
 498 
 499         werr = smbconf_txt_load_file(ctx);
 500         if (!W_ERROR_IS_OK(werr)) {
 501                 return werr;
 502         }
 503 
 504         found = smbconf_find_in_array(service,
 505                                       pd(ctx)->cache->share_names,
 506                                       pd(ctx)->cache->num_shares,
 507                                       &share_index);
 508         if (!found) {
 509                 return WERR_NO_SUCH_SERVICE;
 510         }
 511 
 512         found = smbconf_reverse_find_in_array(param,
 513                                 pd(ctx)->cache->param_names[share_index],
 514                                 pd(ctx)->cache->num_params[share_index],
 515                                 &param_index);
 516         if (!found) {
 517                 return WERR_INVALID_PARAM;
 518         }
 519 
 520         *valstr = talloc_strdup(mem_ctx,
 521                         pd(ctx)->cache->param_values[share_index][param_index]);
 522 
 523         if (*valstr == NULL) {
 524                 return WERR_NOMEM;
 525         }
 526 
 527         return WERR_OK;
 528 }
 529 
 530 /**
 531  * delete a parameter from configuration
 532  */
 533 static WERROR smbconf_txt_delete_parameter(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 534                                            const char *service,
 535                                            const char *param)
 536 {
 537         return WERR_NOT_SUPPORTED;
 538 }
 539 
 540 static WERROR smbconf_txt_get_includes(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 541                                        TALLOC_CTX *mem_ctx,
 542                                        const char *service,
 543                                        uint32_t *num_includes,
 544                                        char ***includes)
 545 {
 546         WERROR werr;
 547         bool found;
 548         uint32_t sidx, count;
 549         TALLOC_CTX *tmp_ctx = NULL;
 550         uint32_t tmp_num_includes = 0;
 551         char **tmp_includes = NULL;
 552 
 553         werr = smbconf_txt_load_file(ctx);
 554         if (!W_ERROR_IS_OK(werr)) {
 555                 return werr;
 556         }
 557 
 558         found = smbconf_find_in_array(service,
 559                                       pd(ctx)->cache->share_names,
 560                                       pd(ctx)->cache->num_shares,
 561                                       &sidx);
 562         if (!found) {
 563                 return WERR_NO_SUCH_SERVICE;
 564         }
 565 
 566         tmp_ctx = talloc_stackframe();
 567 
 568         for (count = 0; count < pd(ctx)->cache->num_params[sidx]; count++) {
 569                 if (strequal(pd(ctx)->cache->param_names[sidx][count],
 570                              "include"))
 571                 {
 572                         werr = smbconf_add_string_to_array(tmp_ctx,
 573                                 &tmp_includes,
 574                                 tmp_num_includes,
 575                                 pd(ctx)->cache->param_values[sidx][count]);
 576                         if (!W_ERROR_IS_OK(werr)) {
 577                                 goto done;
 578                         }
 579                         tmp_num_includes++;
 580                 }
 581         }
 582 
 583         *num_includes = tmp_num_includes;
 584         if (*num_includes > 0) {
 585                 *includes = talloc_move(mem_ctx, &tmp_includes);
 586                 if (*includes == NULL) {
 587                         werr = WERR_NOMEM;
 588                         goto done;
 589                 }
 590         } else {
 591                 *includes = NULL;
 592         }
 593 
 594         werr = WERR_OK;
 595 
 596 done:
 597         talloc_free(tmp_ctx);
 598         return werr;
 599 }
 600 
 601 static WERROR smbconf_txt_set_includes(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 602                                        const char *service,
 603                                        uint32_t num_includes,
 604                                        const char **includes)
 605 {
 606         return WERR_NOT_SUPPORTED;
 607 }
 608 
 609 static WERROR smbconf_txt_delete_includes(struct smbconf_ctx *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 610                                           const char *service)
 611 {
 612         return WERR_NOT_SUPPORTED;
 613 }
 614 
 615 static WERROR smbconf_txt_transaction_start(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 616 {
 617         return WERR_OK;
 618 }
 619 
 620 static WERROR smbconf_txt_transaction_commit(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 621 {
 622         return WERR_OK;
 623 }
 624 
 625 static WERROR smbconf_txt_transaction_cancel(struct smbconf_ctx *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 626 {
 627         return WERR_OK;
 628 }
 629 
 630 static struct smbconf_ops smbconf_ops_txt = {
 631         .init                   = smbconf_txt_init,
 632         .shutdown               = smbconf_txt_shutdown,
 633         .requires_messaging     = smbconf_txt_requires_messaging,
 634         .is_writeable           = smbconf_txt_is_writeable,
 635         .open_conf              = smbconf_txt_open,
 636         .close_conf             = smbconf_txt_close,
 637         .get_csn                = smbconf_txt_get_csn,
 638         .drop                   = smbconf_txt_drop,
 639         .get_share_names        = smbconf_txt_get_share_names,
 640         .share_exists           = smbconf_txt_share_exists,
 641         .create_share           = smbconf_txt_create_share,
 642         .get_share              = smbconf_txt_get_share,
 643         .delete_share           = smbconf_txt_delete_share,
 644         .set_parameter          = smbconf_txt_set_parameter,
 645         .get_parameter          = smbconf_txt_get_parameter,
 646         .delete_parameter       = smbconf_txt_delete_parameter,
 647         .get_includes           = smbconf_txt_get_includes,
 648         .set_includes           = smbconf_txt_set_includes,
 649         .delete_includes        = smbconf_txt_delete_includes,
 650         .transaction_start      = smbconf_txt_transaction_start,
 651         .transaction_commit     = smbconf_txt_transaction_commit,
 652         .transaction_cancel     = smbconf_txt_transaction_cancel,
 653 };
 654 
 655 
 656 /**
 657  * initialize the smbconf text backend
 658  * the only function that is exported from this module
 659  */
 660 WERROR smbconf_init_txt(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 661                         struct smbconf_ctx **conf_ctx,
 662                         const char *path)
 663 {
 664         WERROR werr;
 665 
 666         werr = smbconf_init_internal(mem_ctx, conf_ctx, path, &smbconf_ops_txt);
 667         if (!W_ERROR_IS_OK(werr)) {
 668                 return werr;
 669         }
 670 
 671         return smbconf_txt_load_file(*conf_ctx);
 672 }

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