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