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.

271 lines
6.6KB

  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. #include <stdbool.h>
  16. #include <stdint.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <unistd.h>
  20. #include <fcntl.h>
  21. #include <errno.h>
  22. #include <string.h>
  23. #include <dbus/dbus.h>
  24. #include <time.h>
  25. #include "controller_internal.h"
  26. #include "jackdbus.h"
  27. bool
  28. jack_controller_settings_write_string(int fd, const char * string, void *dbus_call_context_ptr)
  29. {
  30. size_t len;
  31. len = strlen(string);
  32. if (write(fd, string, len) != len)
  33. {
  34. jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "write() failed to write config file.");
  35. return false;
  36. }
  37. return true;
  38. }
  39. struct save_context
  40. {
  41. int fd;
  42. const char *indent;
  43. };
  44. #define save_context_ptr ((struct save_context *)context)
  45. #define fd (save_context_ptr->fd)
  46. bool
  47. jack_controller_settings_write_option(
  48. void *context,
  49. const char *name,
  50. const char *content,
  51. void *dbus_call_context_ptr)
  52. {
  53. if (!jack_controller_settings_write_string(fd, save_context_ptr->indent, dbus_call_context_ptr))
  54. {
  55. return false;
  56. }
  57. if (!jack_controller_settings_write_string(fd, "<option name=\"", dbus_call_context_ptr))
  58. {
  59. return false;
  60. }
  61. if (!jack_controller_settings_write_string(fd, name, dbus_call_context_ptr))
  62. {
  63. return false;
  64. }
  65. if (!jack_controller_settings_write_string(fd, "\">", dbus_call_context_ptr))
  66. {
  67. return false;
  68. }
  69. if (!jack_controller_settings_write_string(fd, content, dbus_call_context_ptr))
  70. {
  71. return false;
  72. }
  73. if (!jack_controller_settings_write_string(fd, "</option>\n", dbus_call_context_ptr))
  74. {
  75. return false;
  76. }
  77. return true;
  78. }
  79. #undef fd
  80. bool
  81. jack_controller_settings_save(
  82. struct jack_controller * controller_ptr,
  83. void *dbus_call_context_ptr)
  84. {
  85. char *filename;
  86. size_t conf_len;
  87. int fd;
  88. bool ret;
  89. time_t timestamp;
  90. char timestamp_str[26];
  91. struct save_context context;
  92. const JSList * node_ptr;
  93. jackctl_driver_t *driver;
  94. time(&timestamp);
  95. ctime_r(&timestamp, timestamp_str);
  96. timestamp_str[24] = 0;
  97. ret = false;
  98. conf_len = strlen(JACKDBUS_CONF);
  99. filename = malloc(g_jackdbus_config_dir_len + conf_len + 1);
  100. if (filename == NULL)
  101. {
  102. jack_error("Out of memory.");
  103. goto exit;
  104. }
  105. memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len);
  106. memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len);
  107. filename[g_jackdbus_config_dir_len + conf_len] = 0;
  108. jack_info("Saving settings to \"%s\" ...", filename);
  109. fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  110. if (fd == -1)
  111. {
  112. jack_error("open() failed to open conf filename. error is %d (%s)", errno, strerror(errno));
  113. goto exit_free_filename;
  114. }
  115. context.fd = fd;
  116. if (!jack_controller_settings_write_string(fd, "<?xml version=\"1.0\"?>\n", dbus_call_context_ptr))
  117. {
  118. goto exit_close;
  119. }
  120. if (!jack_controller_settings_write_string(fd, "<!--\n", dbus_call_context_ptr))
  121. {
  122. goto exit_close;
  123. }
  124. if (!jack_controller_settings_write_string(fd, JACK_CONF_HEADER_TEXT, dbus_call_context_ptr))
  125. {
  126. goto exit_close;
  127. }
  128. if (!jack_controller_settings_write_string(fd, "-->\n", dbus_call_context_ptr))
  129. {
  130. goto exit_close;
  131. }
  132. if (!jack_controller_settings_write_string(fd, "<!-- ", dbus_call_context_ptr))
  133. {
  134. goto exit_close;
  135. }
  136. if (!jack_controller_settings_write_string(fd, timestamp_str, dbus_call_context_ptr))
  137. {
  138. goto exit_close;
  139. }
  140. if (!jack_controller_settings_write_string(fd, " -->\n", dbus_call_context_ptr))
  141. {
  142. goto exit_close;
  143. }
  144. if (!jack_controller_settings_write_string(fd, "<jack>\n", dbus_call_context_ptr))
  145. {
  146. goto exit_close;
  147. }
  148. if (!jack_controller_settings_write_string(fd, " <engine>\n", dbus_call_context_ptr))
  149. {
  150. goto exit_close;
  151. }
  152. context.indent = " ";
  153. if (!jack_controller_settings_save_engine_options(&context, controller_ptr, dbus_call_context_ptr))
  154. {
  155. goto exit_close;
  156. }
  157. if (!jack_controller_settings_write_string(fd, " </engine>\n", dbus_call_context_ptr))
  158. {
  159. goto exit_close;
  160. }
  161. if (!jack_controller_settings_write_string(fd, " <drivers>\n", dbus_call_context_ptr))
  162. {
  163. goto exit_close;
  164. }
  165. node_ptr = jackctl_server_get_drivers_list(controller_ptr->server);
  166. while (node_ptr != NULL)
  167. {
  168. driver = (jackctl_driver_t *)node_ptr->data;
  169. if (!jack_controller_settings_write_string(fd, " <driver name=\"", dbus_call_context_ptr))
  170. {
  171. goto exit_close;
  172. }
  173. if (!jack_controller_settings_write_string(fd, jackctl_driver_get_name(driver), dbus_call_context_ptr))
  174. {
  175. goto exit_close;
  176. }
  177. if (!jack_controller_settings_write_string(fd, "\">\n", dbus_call_context_ptr))
  178. {
  179. goto exit_close;
  180. }
  181. context.indent = " ";
  182. if (!jack_controller_settings_save_driver_options(&context, driver, dbus_call_context_ptr))
  183. {
  184. goto exit_close;
  185. }
  186. if (!jack_controller_settings_write_string(fd, " </driver>\n", dbus_call_context_ptr))
  187. {
  188. goto exit_close;
  189. }
  190. node_ptr = jack_slist_next(node_ptr);
  191. }
  192. if (!jack_controller_settings_write_string(fd, " </drivers>\n", dbus_call_context_ptr))
  193. {
  194. goto exit_close;
  195. }
  196. if (!jack_controller_settings_write_string(fd, "</jack>\n", dbus_call_context_ptr))
  197. {
  198. goto exit_close;
  199. }
  200. ret = true;
  201. exit_close:
  202. close(fd);
  203. exit_free_filename:
  204. free(filename);
  205. exit:
  206. return ret;
  207. }
  208. void
  209. jack_controller_settings_save_auto(
  210. struct jack_controller * controller_ptr)
  211. {
  212. jack_controller_settings_save(controller_ptr, NULL);
  213. }