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.

275 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. #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. time(&timestamp);
  98. ctime_r(&timestamp, timestamp_str);
  99. timestamp_str[24] = 0;
  100. ret = false;
  101. conf_len = strlen(JACKDBUS_CONF);
  102. filename = malloc(g_jackdbus_config_dir_len + conf_len + 1);
  103. if (filename == NULL)
  104. {
  105. jack_error("Out of memory.");
  106. goto exit;
  107. }
  108. memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len);
  109. memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len);
  110. filename[g_jackdbus_config_dir_len + conf_len] = 0;
  111. jack_info("Saving settings to \"%s\" ...", filename);
  112. fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  113. if (fd == -1)
  114. {
  115. jack_error("open() failed to open conf filename. error is %d (%s)", errno, strerror(errno));
  116. goto exit_free_filename;
  117. }
  118. context.fd = fd;
  119. if (!jack_controller_settings_write_string(fd, "<?xml version=\"1.0\"?>\n", dbus_call_context_ptr))
  120. {
  121. goto exit_close;
  122. }
  123. if (!jack_controller_settings_write_string(fd, "<!--\n", dbus_call_context_ptr))
  124. {
  125. goto exit_close;
  126. }
  127. if (!jack_controller_settings_write_string(fd, JACK_CONF_HEADER_TEXT, dbus_call_context_ptr))
  128. {
  129. goto exit_close;
  130. }
  131. if (!jack_controller_settings_write_string(fd, "-->\n", dbus_call_context_ptr))
  132. {
  133. goto exit_close;
  134. }
  135. if (!jack_controller_settings_write_string(fd, "<!-- ", dbus_call_context_ptr))
  136. {
  137. goto exit_close;
  138. }
  139. if (!jack_controller_settings_write_string(fd, timestamp_str, dbus_call_context_ptr))
  140. {
  141. goto exit_close;
  142. }
  143. if (!jack_controller_settings_write_string(fd, " -->\n", dbus_call_context_ptr))
  144. {
  145. goto exit_close;
  146. }
  147. if (!jack_controller_settings_write_string(fd, "<jack>\n", dbus_call_context_ptr))
  148. {
  149. goto exit_close;
  150. }
  151. if (!jack_controller_settings_write_string(fd, " <engine>\n", dbus_call_context_ptr))
  152. {
  153. goto exit_close;
  154. }
  155. context.indent = " ";
  156. if (!jack_controller_settings_save_engine_options(&context, controller_ptr, dbus_call_context_ptr))
  157. {
  158. goto exit_close;
  159. }
  160. if (!jack_controller_settings_write_string(fd, " </engine>\n", dbus_call_context_ptr))
  161. {
  162. goto exit_close;
  163. }
  164. if (!jack_controller_settings_write_string(fd, " <drivers>\n", dbus_call_context_ptr))
  165. {
  166. goto exit_close;
  167. }
  168. node_ptr = jackctl_server_get_drivers_list(controller_ptr->server);
  169. while (node_ptr != NULL)
  170. {
  171. driver = (jackctl_driver_t *)node_ptr->data;
  172. if (!jack_controller_settings_write_string(fd, " <driver name=\"", dbus_call_context_ptr))
  173. {
  174. goto exit_close;
  175. }
  176. if (!jack_controller_settings_write_string(fd, jackctl_driver_get_name(driver), dbus_call_context_ptr))
  177. {
  178. goto exit_close;
  179. }
  180. if (!jack_controller_settings_write_string(fd, "\">\n", dbus_call_context_ptr))
  181. {
  182. goto exit_close;
  183. }
  184. context.indent = " ";
  185. if (!jack_controller_settings_save_driver_options(&context, driver, dbus_call_context_ptr))
  186. {
  187. goto exit_close;
  188. }
  189. if (!jack_controller_settings_write_string(fd, " </driver>\n", dbus_call_context_ptr))
  190. {
  191. goto exit_close;
  192. }
  193. node_ptr = jack_slist_next(node_ptr);
  194. }
  195. if (!jack_controller_settings_write_string(fd, " </drivers>\n", dbus_call_context_ptr))
  196. {
  197. goto exit_close;
  198. }
  199. if (!jack_controller_settings_write_string(fd, "</jack>\n", dbus_call_context_ptr))
  200. {
  201. goto exit_close;
  202. }
  203. ret = true;
  204. exit_close:
  205. close(fd);
  206. exit_free_filename:
  207. free(filename);
  208. exit:
  209. return ret;
  210. }
  211. void
  212. jack_controller_settings_save_auto(
  213. struct jack_controller * controller_ptr)
  214. {
  215. jack_controller_settings_save(controller_ptr, NULL);
  216. }