• 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_conf2dir = UCI_CONF2DIR;
 45 __private const char *uci_savedir = UCI_SAVEDIR;
 46 
 47 /* exported functions */
 48 struct uci_context *uci_alloc_context(void)
 49 {
 50         struct uci_context *ctx;
 51 
 52         ctx = (struct uci_context *) calloc(1, sizeof(struct uci_context));
 53         if (!ctx)
 54                 return NULL;
 55 
 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->conf2dir = (char *) uci_conf2dir;
 63         ctx->savedir = (char *) uci_savedir;
 64         uci_add_delta_path(ctx, uci_savedir);
 65 
 66         uci_list_add(&ctx->backends, &uci_file_backend.e.list);
 67         ctx->backend = &uci_file_backend;
 68 
 69         return ctx;
 70 }
 71 
 72 void uci_free_context(struct uci_context *ctx)
 73 {
 74         struct uci_element *e, *tmp;
 75 
 76         if (ctx->confdir != uci_confdir)
 77                 free(ctx->confdir);
 78         if (ctx->savedir != uci_savedir)
 79                 free(ctx->savedir);
 80 
 81         uci_cleanup(ctx);
 82         UCI_TRAP_SAVE(ctx, ignore);
 83         uci_foreach_element_safe(&ctx->root, tmp, e) {
 84                 struct uci_package *p = uci_to_package(e);
 85                 uci_free_package(&p);
 86         }
 87         uci_foreach_element_safe(&ctx->delta_path, tmp, e) {
 88                 uci_free_element(e);
 89         }
 90         UCI_TRAP_RESTORE(ctx);
 91         free(ctx);
 92 
 93 ignore:
 94         return;
 95 }
 96 
 97 int uci_set_conf2dir(struct uci_context *ctx, const char *dir)
 98 {
 99         char *cdir;
100 
101         if (!dir || !dir[0])
102                 cdir = NULL;
103         else if ((cdir = strdup(dir)) == NULL)
104                 return UCI_ERR_MEM;
105 
106         if (ctx->conf2dir != uci_conf2dir)
107                 free(ctx->conf2dir);
108         ctx->conf2dir = cdir;
109 
110         return 0;
111 }
112 
113 int uci_set_confdir(struct uci_context *ctx, const char *dir)
114 {
115         char *cdir;
116 
117         UCI_HANDLE_ERR(ctx);
118         UCI_ASSERT(ctx, dir != NULL);
119 
120         cdir = uci_strdup(ctx, dir);
121         if (ctx->confdir != uci_confdir)
122                 free(ctx->confdir);
123         ctx->confdir = cdir;
124         return 0;
125 }
126 
127 __private void uci_cleanup(struct uci_context *ctx)
128 {
129         struct uci_parse_context *pctx;
130 
131         if (ctx->buf) {
132                 free(ctx->buf);
133                 ctx->buf = NULL;
134                 ctx->bufsz = 0;
135         }
136 
137         pctx = ctx->pctx;
138         if (!pctx)
139                 return;
140 
141         ctx->pctx = NULL;
142         if (pctx->package)
143                 uci_free_package(&pctx->package);
144 
145         if (pctx->buf)
146                 free(pctx->buf);
147 
148         free(pctx);
149 }
150 
151 void
152 uci_perror(struct uci_context *ctx, const char *str)
153 {
154         uci_get_errorstr(ctx, NULL, str);
155 }
156 
157 void
158 uci_get_errorstr(struct uci_context *ctx, char **dest, const char *prefix)
159 {
160         static char error_info[128] = { 0 };
161         int err;
162 
163         err = ctx ? ctx->err : UCI_ERR_INVAL;
164         if ((err < 0) || (err >= UCI_ERR_LAST))
165                 err = UCI_ERR_UNKNOWN;
166 
167         if (ctx && ctx->pctx && (err == UCI_ERR_PARSE)) {
168                 snprintf(error_info, sizeof(error_info) - 1, " (%s) at line %d, byte %zu",
169                          (ctx->pctx->reason ? ctx->pctx->reason : "unknown"),
170                          ctx->pctx->line, ctx->pctx->byte);
171         }
172 
173         if (!dest) {
174                 strcat(error_info, "\n");
175                 fprintf(stderr, "%s%s%s%s%s%s",
176                         (prefix ? prefix : ""), (prefix ? ": " : ""),
177                         (ctx && ctx->func ? ctx->func : ""), (ctx && ctx->func ? ": " : ""),
178                         uci_errstr[err],
179                         error_info);
180                 return;
181         }
182 
183         err = asprintf(dest, "%s%s%s%s%s%s",
184                 (prefix ? prefix : ""), (prefix ? ": " : ""),
185                 (ctx && ctx->func ? ctx->func : ""), (ctx && ctx->func ? ": " : ""),
186                 uci_errstr[err],
187                 error_info);
188 
189         if (err < 0)
190                 *dest = NULL;
191 }
192 
193 int uci_list_configs(struct uci_context *ctx, char ***list)
194 {
195         UCI_HANDLE_ERR(ctx);
196         UCI_ASSERT(ctx, list != NULL);
197         UCI_ASSERT(ctx, ctx->backend && ctx->backend->list_configs);
198         *list = ctx->backend->list_configs(ctx);
199         return 0;
200 }
201 
202 int uci_commit(struct uci_context *ctx, struct uci_package **package, bool overwrite)
203 {
204         struct uci_package *p;
205         UCI_HANDLE_ERR(ctx);
206         UCI_ASSERT(ctx, package != NULL);
207         p = *package;
208         UCI_ASSERT(ctx, p != NULL);
209         UCI_ASSERT(ctx, p->backend && p->backend->commit);
210         p->backend->commit(ctx, package, overwrite);
211         return 0;
212 }
213 
214 int uci_load(struct uci_context *ctx, const char *name, struct uci_package **package)
215 {
216         struct uci_package *p;
217 
218         UCI_HANDLE_ERR(ctx);
219         UCI_ASSERT(ctx, ctx->backend && ctx->backend->load);
220         p = ctx->backend->load(ctx, name);
221         if (package)
222                 *package = p;
223 
224         return 0;
225 }
226 
227 int uci_set_backend(struct uci_context *ctx, const char *name)
228 {
229         struct uci_element *e;
230 
231         UCI_HANDLE_ERR(ctx);
232         UCI_ASSERT(ctx, name != NULL);
233         e = uci_lookup_list(&ctx->backends, name);
234         if (!e)
235                 UCI_THROW(ctx, UCI_ERR_NOTFOUND);
236         ctx->backend = uci_to_backend(e);
237         return 0;
238 }
239 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt