ucix.c 4.5 KB

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