ucix.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include "include/ucix.h"
  4. static struct uci_ptr ptr;
  5. static inline int ucix_get_ptr(struct uci_context *ctx, const char *p, const char *s, const char *o, const char *t)
  6. {
  7. memset(&ptr, 0, sizeof(ptr));
  8. ptr.package = p;
  9. ptr.section = s;
  10. ptr.option = o;
  11. ptr.value = t;
  12. return uci_lookup_ptr(ctx, &ptr, NULL, true);
  13. }
  14. struct uci_context* ucix_init(const char *config_file)
  15. {
  16. struct uci_context *ctx = uci_alloc_context();
  17. if(!ctx)
  18. return NULL;
  19. uci_add_delta_path(ctx, "/var/state");
  20. if(uci_load(ctx, config_file, NULL) != UCI_OK)
  21. {
  22. printf("%s/%s is missing or corrupt\n", ctx->savedir, config_file);
  23. return NULL;
  24. }
  25. return ctx;
  26. }
  27. struct uci_context* ucix_init_path(const char *path, const char *config_file)
  28. {
  29. struct uci_context *ctx = uci_alloc_context();
  30. if(!ctx)
  31. return NULL;
  32. if(path)
  33. {
  34. uci_set_savedir(ctx, path);
  35. }
  36. if(uci_load(ctx, config_file, NULL) != UCI_OK)
  37. {
  38. printf("%s/%s is missing or corrupt\n", ctx->savedir, config_file);
  39. return NULL;
  40. }
  41. return ctx;
  42. }
  43. void ucix_cleanup(struct uci_context *ctx)
  44. {
  45. if(ctx)
  46. {
  47. uci_free_context(ctx);
  48. }
  49. }
  50. int ucix_save(struct uci_context *ctx, const char *p)
  51. {
  52. if(ucix_get_ptr(ctx, p, NULL, NULL, NULL))
  53. return 1;
  54. uci_set_savedir(ctx, "/tmp/.uci/");
  55. uci_save(ctx, ptr.p);
  56. return 0;
  57. }
  58. int ucix_save_state(struct uci_context *ctx, const char *p)
  59. {
  60. if(ucix_get_ptr(ctx, p, NULL, NULL, NULL))
  61. return 1;
  62. uci_set_savedir(ctx, "/var/state/");
  63. uci_save(ctx, ptr.p);
  64. return 0;
  65. }
  66. int ucix_get_option_list(struct uci_context *ctx, const char *p,
  67. const char *s, const char *o, struct list_head *l)
  68. {
  69. struct uci_element *e = NULL;
  70. if(ucix_get_ptr(ctx, p, s, o, NULL))
  71. return 1;
  72. if (!(ptr.flags & UCI_LOOKUP_COMPLETE))
  73. return 1;
  74. e = ptr.last;
  75. switch (e->type)
  76. {
  77. case UCI_TYPE_OPTION:
  78. switch(ptr.o->type) {
  79. case UCI_TYPE_LIST:
  80. uci_foreach_element(&ptr.o->v.list, e)
  81. {
  82. struct ucilist *ul = malloc(sizeof(struct ucilist));
  83. ul->val = strdup((e->name)?(e->name):(""));
  84. INIT_LIST_HEAD(&ul->list);
  85. list_add(&ul->list, l);
  86. }
  87. break;
  88. default:
  89. break;
  90. }
  91. break;
  92. default:
  93. return 1;
  94. }
  95. return 0;
  96. }
  97. char* ucix_get_option(struct uci_context *ctx, const char *p, const char *s, const char *o)
  98. {
  99. struct uci_element *e = NULL;
  100. const char *value = NULL;
  101. if(ucix_get_ptr(ctx, p, s, o, NULL))
  102. return NULL;
  103. if (!(ptr.flags & UCI_LOOKUP_COMPLETE))
  104. return NULL;
  105. e = ptr.last;
  106. switch (e->type)
  107. {
  108. case UCI_TYPE_SECTION:
  109. value = uci_to_section(e)->type;
  110. break;
  111. case UCI_TYPE_OPTION:
  112. switch(ptr.o->type) {
  113. case UCI_TYPE_STRING:
  114. value = ptr.o->v.string;
  115. break;
  116. default:
  117. value = NULL;
  118. break;
  119. }
  120. break;
  121. default:
  122. return 0;
  123. }
  124. return (value) ? (strdup(value)):(NULL);
  125. }
  126. int ucix_get_option_int(struct uci_context *ctx, const char *p, const char *s, const char *o, int def)
  127. {
  128. char *tmp = ucix_get_option(ctx, p, s, o);
  129. int ret = def;
  130. if (tmp)
  131. {
  132. ret = atoi(tmp);
  133. free(tmp);
  134. }
  135. return ret;
  136. }
  137. void ucix_add_section(struct uci_context *ctx, const char *p, const char *s, const char *t)
  138. {
  139. if(ucix_get_ptr(ctx, p, s, NULL, t))
  140. return;
  141. uci_set(ctx, &ptr);
  142. }
  143. void ucix_add_option(struct uci_context *ctx, const char *p, const char *s, const char *o, const char *t)
  144. {
  145. if(ucix_get_ptr(ctx, p, s, o, (t)?(t):("")))
  146. return;
  147. uci_set(ctx, &ptr);
  148. }
  149. void ucix_add_option_int(struct uci_context *ctx, const char *p, const char *s, const char *o, int t)
  150. {
  151. char tmp[64];
  152. snprintf(tmp, 64, "%d", t);
  153. ucix_add_option(ctx, p, s, o, tmp);
  154. }
  155. void ucix_del(struct uci_context *ctx, const char *p, const char *s, const char *o)
  156. {
  157. if(!ucix_get_ptr(ctx, p, s, o, NULL))
  158. uci_delete(ctx, &ptr);
  159. }
  160. void ucix_revert(struct uci_context *ctx, const char *p, const char *s, const char *o)
  161. {
  162. if(!ucix_get_ptr(ctx, p, s, o, NULL))
  163. uci_revert(ctx, &ptr);
  164. }
  165. void ucix_for_each_section_type(struct uci_context *ctx,
  166. const char *p, const char *t,
  167. void (*cb)(const char*, void*), void *priv)
  168. {
  169. struct uci_element *e;
  170. if(ucix_get_ptr(ctx, p, NULL, NULL, NULL))
  171. return;
  172. uci_foreach_element(&ptr.p->sections, e)
  173. if (!strcmp(t, uci_to_section(e)->type))
  174. cb(e->name, priv);
  175. }
  176. void ucix_for_each_section_option(struct uci_context *ctx,
  177. const char *p, const char *s,
  178. void (*cb)(const char*, const char*, void*), void *priv)
  179. {
  180. struct uci_element *e;
  181. if(ucix_get_ptr(ctx, p, s, NULL, NULL))
  182. return;
  183. uci_foreach_element(&ptr.s->options, e)
  184. {
  185. struct uci_option *o = uci_to_option(e);
  186. cb(o->e.name, o->v.string, priv);
  187. }
  188. }
  189. int ucix_commit(struct uci_context *ctx, const char *p)
  190. {
  191. if(ucix_get_ptr(ctx, p, NULL, NULL, NULL))
  192. return 1;
  193. return uci_commit(ctx, &ptr.p, false);
  194. }