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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt