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.

328 lines
8.0KB

  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. int fd;
  45. const char *indent;
  46. };
  47. #define save_context_ptr ((struct save_context *)context)
  48. #define fd (save_context_ptr->fd)
  49. bool
  50. jack_controller_settings_write_option(
  51. void *context,
  52. const char *name,
  53. const char *content,
  54. void *dbus_call_context_ptr)
  55. {
  56. if (!jack_controller_settings_write_string(fd, save_context_ptr->indent, dbus_call_context_ptr))
  57. {
  58. return false;
  59. }
  60. if (!jack_controller_settings_write_string(fd, "<option name=\"", dbus_call_context_ptr))
  61. {
  62. return false;
  63. }
  64. if (!jack_controller_settings_write_string(fd, name, dbus_call_context_ptr))
  65. {
  66. return false;
  67. }
  68. if (!jack_controller_settings_write_string(fd, "\">", dbus_call_context_ptr))
  69. {
  70. return false;
  71. }
  72. if (!jack_controller_settings_write_string(fd, content, dbus_call_context_ptr))
  73. {
  74. return false;
  75. }
  76. if (!jack_controller_settings_write_string(fd, "</option>\n", dbus_call_context_ptr))
  77. {
  78. return false;
  79. }
  80. return true;
  81. }
  82. #undef fd
  83. bool
  84. jack_controller_settings_save(
  85. struct jack_controller * controller_ptr,
  86. void *dbus_call_context_ptr)
  87. {
  88. char *filename;
  89. size_t conf_len;
  90. int fd;
  91. bool ret;
  92. time_t timestamp;
  93. char timestamp_str[26];
  94. struct save_context context;
  95. const JSList * node_ptr;
  96. jackctl_driver_t *driver;
  97. jackctl_internal_t *internal;
  98. time(&timestamp);
  99. ctime_r(&timestamp, timestamp_str);
  100. timestamp_str[24] = 0;
  101. ret = false;
  102. conf_len = strlen(JACKDBUS_CONF);
  103. filename = malloc(g_jackdbus_config_dir_len + conf_len + 1);
  104. if (filename == NULL)
  105. {
  106. jack_error("Out of memory.");
  107. goto exit;
  108. }
  109. memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len);
  110. memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len);
  111. filename[g_jackdbus_config_dir_len + conf_len] = 0;
  112. jack_info("Saving settings to \"%s\" ...", filename);
  113. fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  114. if (fd == -1)
  115. {
  116. jack_error("open() failed to open conf filename. error is %d (%s)", errno, strerror(errno));
  117. goto exit_free_filename;
  118. }
  119. context.fd = fd;
  120. if (!jack_controller_settings_write_string(fd, "<?xml version=\"1.0\"?>\n", dbus_call_context_ptr))
  121. {
  122. goto exit_close;
  123. }
  124. if (!jack_controller_settings_write_string(fd, "<!--\n", dbus_call_context_ptr))
  125. {
  126. goto exit_close;
  127. }
  128. if (!jack_controller_settings_write_string(fd, JACK_CONF_HEADER_TEXT, dbus_call_context_ptr))
  129. {
  130. goto exit_close;
  131. }
  132. if (!jack_controller_settings_write_string(fd, "-->\n", dbus_call_context_ptr))
  133. {
  134. goto exit_close;
  135. }
  136. if (!jack_controller_settings_write_string(fd, "<!-- ", dbus_call_context_ptr))
  137. {
  138. goto exit_close;
  139. }
  140. if (!jack_controller_settings_write_string(fd, timestamp_str, dbus_call_context_ptr))
  141. {
  142. goto exit_close;
  143. }
  144. if (!jack_controller_settings_write_string(fd, " -->\n", dbus_call_context_ptr))
  145. {
  146. goto exit_close;
  147. }
  148. if (!jack_controller_settings_write_string(fd, "<jack>\n", dbus_call_context_ptr))
  149. {
  150. goto exit_close;
  151. }
  152. /* engine */
  153. if (!jack_controller_settings_write_string(fd, " <engine>\n", dbus_call_context_ptr))
  154. {
  155. goto exit_close;
  156. }
  157. context.indent = " ";
  158. if (!jack_controller_settings_save_engine_options(&context, controller_ptr, dbus_call_context_ptr))
  159. {
  160. goto exit_close;
  161. }
  162. if (!jack_controller_settings_write_string(fd, " </engine>\n", dbus_call_context_ptr))
  163. {
  164. goto exit_close;
  165. }
  166. /* drivers */
  167. if (!jack_controller_settings_write_string(fd, " <drivers>\n", dbus_call_context_ptr))
  168. {
  169. goto exit_close;
  170. }
  171. node_ptr = jackctl_server_get_drivers_list(controller_ptr->server);
  172. while (node_ptr != NULL)
  173. {
  174. driver = (jackctl_driver_t *)node_ptr->data;
  175. if (!jack_controller_settings_write_string(fd, " <driver name=\"", dbus_call_context_ptr))
  176. {
  177. goto exit_close;
  178. }
  179. if (!jack_controller_settings_write_string(fd, jackctl_driver_get_name(driver), dbus_call_context_ptr))
  180. {
  181. goto exit_close;
  182. }
  183. if (!jack_controller_settings_write_string(fd, "\">\n", dbus_call_context_ptr))
  184. {
  185. goto exit_close;
  186. }
  187. context.indent = " ";
  188. if (!jack_controller_settings_save_driver_options(&context, driver, dbus_call_context_ptr))
  189. {
  190. goto exit_close;
  191. }
  192. if (!jack_controller_settings_write_string(fd, " </driver>\n", dbus_call_context_ptr))
  193. {
  194. goto exit_close;
  195. }
  196. node_ptr = jack_slist_next(node_ptr);
  197. }
  198. if (!jack_controller_settings_write_string(fd, " </drivers>\n", dbus_call_context_ptr))
  199. {
  200. goto exit_close;
  201. }
  202. /* internals */
  203. if (!jack_controller_settings_write_string(fd, " <internals>\n", dbus_call_context_ptr))
  204. {
  205. goto exit_close;
  206. }
  207. node_ptr = jackctl_server_get_internals_list(controller_ptr->server);
  208. while (node_ptr != NULL)
  209. {
  210. internal = (jackctl_internal_t *)node_ptr->data;
  211. if (!jack_controller_settings_write_string(fd, " <internal name=\"", dbus_call_context_ptr))
  212. {
  213. goto exit_close;
  214. }
  215. if (!jack_controller_settings_write_string(fd, jackctl_internal_get_name(internal), dbus_call_context_ptr))
  216. {
  217. goto exit_close;
  218. }
  219. if (!jack_controller_settings_write_string(fd, "\">\n", dbus_call_context_ptr))
  220. {
  221. goto exit_close;
  222. }
  223. context.indent = " ";
  224. if (!jack_controller_settings_save_internal_options(&context, internal, dbus_call_context_ptr))
  225. {
  226. goto exit_close;
  227. }
  228. if (!jack_controller_settings_write_string(fd, " </internal>\n", dbus_call_context_ptr))
  229. {
  230. goto exit_close;
  231. }
  232. node_ptr = jack_slist_next(node_ptr);
  233. }
  234. if (!jack_controller_settings_write_string(fd, " </internals>\n", dbus_call_context_ptr))
  235. {
  236. goto exit_close;
  237. }
  238. if (!jack_controller_settings_write_string(fd, "</jack>\n", dbus_call_context_ptr))
  239. {
  240. goto exit_close;
  241. }
  242. ret = true;
  243. exit_close:
  244. close(fd);
  245. exit_free_filename:
  246. free(filename);
  247. exit:
  248. return ret;
  249. }
  250. void
  251. jack_controller_settings_save_auto(
  252. struct jack_controller * controller_ptr)
  253. {
  254. jack_controller_settings_save(controller_ptr, NULL);
  255. }