jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
7.7KB

  1. /* -*- Mode: C ; c-basic-offset: 4 -*- */
  2. /*
  3. Copyright (C) 2007,2008 Nedko Arnaudov
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #if defined(HAVE_CONFIG_H)
  16. #include "config.h"
  17. #endif
  18. #include <stdbool.h>
  19. #include <stdint.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <unistd.h>
  23. #include <fcntl.h>
  24. #include <errno.h>
  25. #include <string.h>
  26. #include <dbus/dbus.h>
  27. #include <time.h>
  28. #include "controller_internal.h"
  29. #include "jackdbus.h"
  30. bool
  31. jack_controller_settings_write_string(int fd, const char * string, void *dbus_call_context_ptr)
  32. {
  33. size_t len;
  34. len = strlen(string);
  35. if (write(fd, string, len) != len)
  36. {
  37. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "write() failed to write config file.");
  38. return false;
  39. }
  40. return true;
  41. }
  42. struct save_context
  43. {
  44. void * call;
  45. int fd;
  46. const char * indent;
  47. jack_params_handle params;
  48. const char * address[PARAM_ADDRESS_SIZE];
  49. const char * str;
  50. };
  51. #define ctx_ptr ((struct save_context *)context)
  52. #define fd (ctx_ptr->fd)
  53. static bool jack_controller_serialize_parameter(void * context, const struct jack_parameter * param_ptr)
  54. {
  55. char value[JACK_PARAM_STRING_MAX + 1];
  56. if (!param_ptr->vtable.is_set(param_ptr->obj))
  57. {
  58. return true;
  59. }
  60. jack_controller_serialize_parameter_value(param_ptr, value);
  61. return
  62. jack_controller_settings_write_string(fd, ctx_ptr->indent, ctx_ptr->call) &&
  63. jack_controller_settings_write_string(fd, "<option name=\"", ctx_ptr->call) &&
  64. jack_controller_settings_write_string(fd, param_ptr->name, ctx_ptr->call) &&
  65. jack_controller_settings_write_string(fd, "\">", ctx_ptr->call) &&
  66. jack_controller_settings_write_string(fd, value, ctx_ptr->call) &&
  67. jack_controller_settings_write_string(fd, "</option>\n", ctx_ptr->call);
  68. }
  69. bool serialize_modules(void * context, const char * name)
  70. {
  71. ctx_ptr->indent = " ";
  72. ctx_ptr->address[1] = name;
  73. ctx_ptr->address[2] = NULL;
  74. return
  75. jack_controller_settings_write_string(fd, " <", ctx_ptr->call) &&
  76. jack_controller_settings_write_string(fd, ctx_ptr->str, ctx_ptr->call) &&
  77. jack_controller_settings_write_string(fd, " name=\"", ctx_ptr->call) &&
  78. jack_controller_settings_write_string(fd, name, ctx_ptr->call) &&
  79. jack_controller_settings_write_string(fd, "\">\n", ctx_ptr->call) &&
  80. jack_params_iterate_params(ctx_ptr->params, ctx_ptr->address, jack_controller_serialize_parameter, ctx_ptr) &&
  81. jack_controller_settings_write_string(fd, " </", ctx_ptr->call) &&
  82. jack_controller_settings_write_string(fd, ctx_ptr->str, ctx_ptr->call) &&
  83. jack_controller_settings_write_string(fd, ">\n", ctx_ptr->call);
  84. }
  85. #undef fd
  86. #undef ctx_ptr
  87. bool
  88. jack_controller_settings_save(
  89. struct jack_controller * controller_ptr,
  90. void *dbus_call_context_ptr)
  91. {
  92. char *filename;
  93. size_t conf_len;
  94. int fd;
  95. bool ret;
  96. time_t timestamp;
  97. char timestamp_str[26];
  98. struct save_context context;
  99. const char * modules[] = {"driver", "internal", NULL};
  100. char buffer[100];
  101. unsigned int i;
  102. time(&timestamp);
  103. ctime_r(&timestamp, timestamp_str);
  104. timestamp_str[24] = 0;
  105. ret = false;
  106. conf_len = strlen(JACKDBUS_CONF);
  107. filename = malloc(g_jackdbus_config_dir_len + conf_len + 1);
  108. if (filename == NULL)
  109. {
  110. jack_error("Out of memory.");
  111. goto exit;
  112. }
  113. memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len);
  114. memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len);
  115. filename[g_jackdbus_config_dir_len + conf_len] = 0;
  116. jack_info("Saving settings to \"%s\" ...", filename);
  117. fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  118. if (fd == -1)
  119. {
  120. jack_error("open() failed to open conf filename. error is %d (%s)", errno, strerror(errno));
  121. goto exit_free_filename;
  122. }
  123. context.fd = fd;
  124. context.call = dbus_call_context_ptr;
  125. if (!jack_controller_settings_write_string(fd, "<?xml version=\"1.0\"?>\n", dbus_call_context_ptr))
  126. {
  127. goto exit_close;
  128. }
  129. if (!jack_controller_settings_write_string(fd, "<!--\n", dbus_call_context_ptr))
  130. {
  131. goto exit_close;
  132. }
  133. if (!jack_controller_settings_write_string(fd, JACK_CONF_HEADER_TEXT, dbus_call_context_ptr))
  134. {
  135. goto exit_close;
  136. }
  137. if (!jack_controller_settings_write_string(fd, "-->\n", dbus_call_context_ptr))
  138. {
  139. goto exit_close;
  140. }
  141. if (!jack_controller_settings_write_string(fd, "<!-- ", dbus_call_context_ptr))
  142. {
  143. goto exit_close;
  144. }
  145. if (!jack_controller_settings_write_string(fd, timestamp_str, dbus_call_context_ptr))
  146. {
  147. goto exit_close;
  148. }
  149. if (!jack_controller_settings_write_string(fd, " -->\n", dbus_call_context_ptr))
  150. {
  151. goto exit_close;
  152. }
  153. if (!jack_controller_settings_write_string(fd, "<jack>\n", dbus_call_context_ptr))
  154. {
  155. goto exit_close;
  156. }
  157. /* engine */
  158. if (!jack_controller_settings_write_string(fd, " <engine>\n", dbus_call_context_ptr))
  159. {
  160. goto exit_close;
  161. }
  162. context.indent = " ";
  163. context.address[0] = PTNODE_ENGINE;
  164. context.address[1] = NULL;
  165. if (!jack_params_iterate_params(controller_ptr->params, context.address, jack_controller_serialize_parameter, &context))
  166. {
  167. goto exit_close;
  168. }
  169. if (!jack_controller_settings_write_string(fd, " </engine>\n", dbus_call_context_ptr))
  170. {
  171. goto exit_close;
  172. }
  173. for (i = 0; modules[i] != NULL; i++)
  174. {
  175. if (!jack_controller_settings_write_string(fd, " <", dbus_call_context_ptr))
  176. {
  177. goto exit_close;
  178. }
  179. if (!jack_controller_settings_write_string(fd, modules[i], dbus_call_context_ptr))
  180. {
  181. goto exit_close;
  182. }
  183. if (!jack_controller_settings_write_string(fd, "s>\n", dbus_call_context_ptr))
  184. {
  185. goto exit_close;
  186. }
  187. context.indent = " ";
  188. context.params = controller_ptr->params;
  189. context.str = modules[i];
  190. strcpy(buffer, modules[i]);
  191. strcat(buffer, "s");
  192. context.address[0] = buffer;
  193. context.address[1] = NULL;
  194. if (!jack_params_iterate_container(controller_ptr->params, context.address, serialize_modules, &context))
  195. {
  196. goto exit_close;
  197. }
  198. if (!jack_controller_settings_write_string(fd, " </", dbus_call_context_ptr))
  199. {
  200. goto exit_close;
  201. }
  202. if (!jack_controller_settings_write_string(fd, modules[i], dbus_call_context_ptr))
  203. {
  204. goto exit_close;
  205. }
  206. if (!jack_controller_settings_write_string(fd, "s>\n", dbus_call_context_ptr))
  207. {
  208. goto exit_close;
  209. }
  210. }
  211. if (!jack_controller_settings_write_string(fd, "</jack>\n", dbus_call_context_ptr))
  212. {
  213. goto exit_close;
  214. }
  215. ret = true;
  216. exit_close:
  217. close(fd);
  218. exit_free_filename:
  219. free(filename);
  220. exit:
  221. return ret;
  222. }
  223. void
  224. jack_controller_settings_save_auto(
  225. struct jack_controller * controller_ptr)
  226. {
  227. jack_controller_settings_save(controller_ptr, NULL);
  228. }