• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/uci/libuci.c

  1 /*
  2  * libuci - Library for the Unified Configuration Interface
  3  * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
  4  *
  5  * This program is free software; you can redistribute it and/or modify
  6  * it under the terms of the GNU Lesser General Public License version 2.1
  7  * as published by the Free Software Foundation
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12  * GNU Lesser General Public License for more details.
 13  */
 14 
 15 /*
 16  * This file contains some common code for the uci library
 17  */
 18 
 19 #define _GNU_SOURCE
 20 #include <sys/types.h>
 21 #include <stdbool.h>
 22 #include <string.h>
 23 #include <stdlib.h>
 24 #include <stdio.h>
 25 #include <dlfcn.h>
 26 #include <glob.h>
 27 #include "uci.h"
 28 
 29 static const char *uci_errstr[] = {
 30         [UCI_OK] =            "Success",
 31         [UCI_ERR_MEM] =       "Out of memory",
 32         [UCI_ERR_INVAL] =     "Invalid argument",
 33         [UCI_ERR_NOTFOUND] =  "Entry not found",
 34         [UCI_ERR_IO] =        "I/O error",
 35         [UCI_ERR_PARSE] =     "Parse error",
 36         [UCI_ERR_DUPLICATE] = "Duplicate entry",
 37         [UCI_ERR_UNKNOWN] =   "Unknown error",
 38 };
 39 
 40 #include "uci_internal.h"
 41 #include "list.c"
 42 
 43 __private const char *uci_confdir = UCI_CONFDIR;
 44 __private const char *uci_savedir = UCI_SAVEDIR;
 45 
 46 /* exported functions */
 47 struct uci_context *uci_alloc_context(void)
 48 {
 49         struct uci_context *ctx;
 50 
 51         ctx = (struct uci_context *) malloc(sizeof(struct uci_context));
 52         if (!ctx)
 53                 return NULL;
 54 
 55         memset(ctx, 0, sizeof(struct uci_context));
 56         uci_list_init(&ctx->root);
 57         uci_list_init(&ctx->delta_path);
 58         uci_list_init(&ctx->backends);
 59         ctx->flags = UCI_FLAG_STRICT | UCI_FLAG_SAVED_DELTA;
 60 
 61         ctx->confdir = (char *) uci_confdir;
 62         ctx->savedir = (char *) uci_savedir;
 63         uci_add_delta_path(ctx, uci_savedir);
 64 
 65         uci_list_add(&ctx->backends, &uci_file_backend.e.list);
 66         ctx->backend = &uci_file_backend;
 67 
 68         return ctx;
 69 }
 70 
 71 void uci_free_context(struct uci_context *ctx)
 72 {
 73         struct uci_element *e, *tmp;
 74 
 75         if (ctx->confdir != uci_confdir)
 76                 free(ctx->confdir);
 77         if (ctx->savedir != uci_savedir)
 78                 free(ctx->savedir);
 79 
 80         uci_cleanup(ctx);
 81         UCI_TRAP_SAVE(ctx, ignore);
 82         uci_foreach_element_safe(&ctx->root, tmp, e) {
 83                 struct uci_package *p = uci_to_package(e);
 84                 uci_free_package(&p);
 85         }
 86         uci_foreach_element_safe(&ctx->delta_path, tmp, e) {
 87                 uci_free_element(e);
 88         }
 89         UCI_TRAP_RESTORE(ctx);
 90         free(ctx);
 91 
 92 ignore:
 93         return;
 94 }
 95 
 96 int uci_set_confdir(struct uci_context *ctx, const char *dir)
 97 {
 98         char *cdir;
 99 
100         UCI_HANDLE_ERR(ctx);
101         UCI_ASSERT(ctx, dir != NULL);
102 
103         cdir = uci_strdup(ctx, dir);
104         if (ctx->confdir != uci_confdir)
105                 free(ctx->confdir);
106         ctx->confdir = cdir;
107         return 0;
108 }
109 
110 __private void uci_cleanup(struct uci_context *ctx)
111 {
112         struct uci_parse_context *pctx;
113 
114         if (ctx->buf) {
115                 free(ctx->buf);
116                 ctx->buf = NULL;
117                 ctx->bufsz = 0;
118         }
119 
120         pctx = ctx->pctx;
121         if (!pctx)
122                 return;
123 
124         ctx->pctx = NULL;
125         if (pctx->package)
126                 uci_free_package(&pctx->package);
127 
128         if (pctx->buf)
129                 free(pctx->buf);
130 
131         free(pctx);
132 }
133 
134 void
135 uci_perror(struct uci_context *ctx, const char *str)
136 {
137         uci_get_errorstr(ctx, NULL, str);
138 }
139 
140 void
141 uci_get_errorstr(struct uci_context *ctx, char **dest, const char *prefix)
142 {
143         static char error_info[128] = { 0 };
144         int err;
145 
146         err = ctx ? ctx->err : UCI_ERR_INVAL;
147         if ((err < 0) || (err >= UCI_ERR_LAST))
148                 err = UCI_ERR_UNKNOWN;
149 
150         if (ctx && ctx->pctx && (err == UCI_ERR_PARSE)) {
151                 snprintf(error_info, sizeof(error_info) - 1, " (%s) at line %d, byte %d",
152                          (ctx->pctx->reason ? ctx->pctx->reason : "unknown"),
153                          ctx->pctx->line, ctx->pctx->byte);
154         }
155 
156         if (!dest) {
157                 strcat(error_info, "\n");
158                 fprintf(stderr, "%s%s%s%s%s%s",
159                         (prefix ? prefix : ""), (prefix ? ": " : ""),
160                         (ctx && ctx->func ? ctx->func : ""), (ctx && ctx->func ? ": " : ""),
161                         uci_errstr[err],
162                         error_info);
163                 return;
164         }
165 
166         err = asprintf(dest, "%s%s%s%s%s%s",
167                 (prefix ? prefix : ""), (prefix ? ": " : ""),
168                 (ctx && ctx->func ? ctx->func : ""), (ctx && ctx->func ? ": " : ""),
169                 uci_errstr[err],
170                 error_info);
171 
172         if (err < 0)
173                 *dest = NULL;
174 }
175 
176 int uci_list_configs(struct uci_context *ctx, char ***list)
177 {
178         UCI_HANDLE_ERR(ctx);
179         UCI_ASSERT(ctx, list != NULL);
180         UCI_ASSERT(ctx, ctx->backend && ctx->backend->list_configs);
181         *list = ctx->backend->list_configs(ctx);
182         return 0;
183 }
184 
185 int uci_commit(struct uci_context *ctx, struct uci_package **package, bool overwrite)
186 {
187         struct uci_package *p;
188         UCI_HANDLE_ERR(ctx);
189         UCI_ASSERT(ctx, package != NULL);
190         p = *package;
191         UCI_ASSERT(ctx, p != NULL);
192         UCI_ASSERT(ctx, p->backend && p->backend->commit);
193         p->backend->commit(ctx, package, overwrite);
194         return 0;
195 }
196 
197 int uci_load(struct uci_context *ctx, const char *name, struct uci_package **package)
198 {
199         struct uci_package *p;
200 
201         UCI_HANDLE_ERR(ctx);
202         UCI_ASSERT(ctx, ctx->backend && ctx->backend->load);
203         p = ctx->backend->load(ctx, name);
204         if (package)
205                 *package = p;
206 
207         return 0;
208 }
209 
210 int uci_set_backend(struct uci_context *ctx, const char *name)
211 {
212         struct uci_element *e;
213 
214         UCI_HANDLE_ERR(ctx);
215         UCI_ASSERT(ctx, name != NULL);
216         e = uci_lookup_list(&ctx->backends, name);
217         if (!e)
218                 UCI_THROW(ctx, UCI_ERR_NOTFOUND);
219         ctx->backend = uci_to_backend(e);
220         return 0;
221 }
222 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt