• 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         error_info[0] = '\0';
164 
165         err = ctx ? ctx->err : UCI_ERR_INVAL;
166         if ((err < 0) || (err >= UCI_ERR_LAST))
167                 err = UCI_ERR_UNKNOWN;
168 
169         if (ctx && ctx->pctx && (err == UCI_ERR_PARSE)) {
170                 snprintf(error_info, sizeof(error_info) - 1, " (%s) at line %d, byte %zu",
171                          (ctx->pctx->reason ? ctx->pctx->reason : "unknown"),
172                          ctx->pctx->line, ctx->pctx->byte);
173         }
174 
175         if (!dest) {
176                 strcat(error_info, "\n");
177                 fprintf(stderr, "%s%s%s%s%s%s",
178                         (prefix ? prefix : ""), (prefix ? ": " : ""),
179                         (ctx && ctx->func ? ctx->func : ""), (ctx && ctx->func ? ": " : ""),
180                         uci_errstr[err],
181                         error_info);
182                 return;
183         }
184 
185         err = asprintf(dest, "%s%s%s%s%s%s",
186                 (prefix ? prefix : ""), (prefix ? ": " : ""),
187                 (ctx && ctx->func ? ctx->func : ""), (ctx && ctx->func ? ": " : ""),
188                 uci_errstr[err],
189                 error_info);
190 
191         if (err < 0)
192                 *dest = NULL;
193 }
194 
195 int uci_list_configs(struct uci_context *ctx, char ***list)
196 {
197         UCI_HANDLE_ERR(ctx);
198         UCI_ASSERT(ctx, list != NULL);
199         UCI_ASSERT(ctx, ctx->backend && ctx->backend->list_configs);
200         *list = ctx->backend->list_configs(ctx);
201         return 0;
202 }
203 
204 int uci_commit(struct uci_context *ctx, struct uci_package **package, bool overwrite)
205 {
206         struct uci_package *p;
207         UCI_HANDLE_ERR(ctx);
208         UCI_ASSERT(ctx, package != NULL);
209         p = *package;
210         UCI_ASSERT(ctx, p != NULL);
211         UCI_ASSERT(ctx, p->backend && p->backend->commit);
212         p->backend->commit(ctx, package, overwrite);
213         return 0;
214 }
215 
216 int uci_load(struct uci_context *ctx, const char *name, struct uci_package **package)
217 {
218         struct uci_package *p;
219 
220         UCI_HANDLE_ERR(ctx);
221         UCI_ASSERT(ctx, ctx->backend && ctx->backend->load);
222         p = ctx->backend->load(ctx, name);
223         if (package)
224                 *package = p;
225 
226         return 0;
227 }
228 
229 int uci_set_backend(struct uci_context *ctx, const char *name)
230 {
231         struct uci_element *e;
232 
233         UCI_HANDLE_ERR(ctx);
234         UCI_ASSERT(ctx, name != NULL);
235         e = uci_lookup_list(&ctx->backends, name);
236         if (!e)
237                 UCI_THROW(ctx, UCI_ERR_NOTFOUND);
238         ctx->backend = uci_to_backend(e);
239         return 0;
240 }
241 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt