Merge branch 'master' into port_register_notification_defer
[jack2.git] / dbus / xml_write_raw.c
blob8542c31bbba647b276ae0611c2a2134f3b990c20
1 /* -*- Mode: C ; c-basic-offset: 4 -*- */
2 /*
3 Copyright (C) 2007,2008 Nedko Arnaudov
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #if defined(HAVE_CONFIG_H)
21 #include "config.h"
22 #endif
24 #include <stdbool.h>
25 #include <stdint.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <dbus/dbus.h>
33 #include <time.h>
35 #include "controller_internal.h"
36 #include "jackdbus.h"
38 bool
39 jack_controller_settings_write_string(int fd, const char * string, void *dbus_call_context_ptr)
41 size_t len;
43 len = strlen(string);
45 if (write(fd, string, len) != len)
47 jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "write() failed to write config file.");
48 return false;
51 return true;
54 struct save_context
56 int fd;
57 const char *indent;
60 #define save_context_ptr ((struct save_context *)context)
61 #define fd (save_context_ptr->fd)
63 bool
64 jack_controller_settings_write_option(
65 void *context,
66 const char *name,
67 const char *content,
68 void *dbus_call_context_ptr)
70 if (!jack_controller_settings_write_string(fd, save_context_ptr->indent, dbus_call_context_ptr))
72 return false;
75 if (!jack_controller_settings_write_string(fd, "<option name=\"", dbus_call_context_ptr))
77 return false;
80 if (!jack_controller_settings_write_string(fd, name, dbus_call_context_ptr))
82 return false;
85 if (!jack_controller_settings_write_string(fd, "\">", dbus_call_context_ptr))
87 return false;
90 if (!jack_controller_settings_write_string(fd, content, dbus_call_context_ptr))
92 return false;
95 if (!jack_controller_settings_write_string(fd, "</option>\n", dbus_call_context_ptr))
97 return false;
100 return true;
103 #undef fd
105 bool
106 jack_controller_settings_save(
107 struct jack_controller * controller_ptr,
108 void *dbus_call_context_ptr)
110 char *filename;
111 size_t conf_len;
112 int fd;
113 bool ret;
114 time_t timestamp;
115 char timestamp_str[26];
116 struct save_context context;
117 const JSList * node_ptr;
118 jackctl_driver_t *driver;
119 jackctl_internal_t *internal;
121 time(&timestamp);
122 ctime_r(&timestamp, timestamp_str);
123 timestamp_str[24] = 0;
125 ret = false;
127 conf_len = strlen(JACKDBUS_CONF);
129 filename = malloc(g_jackdbus_config_dir_len + conf_len + 1);
130 if (filename == NULL)
132 jack_error("Out of memory.");
133 goto exit;
136 memcpy(filename, g_jackdbus_config_dir, g_jackdbus_config_dir_len);
137 memcpy(filename + g_jackdbus_config_dir_len, JACKDBUS_CONF, conf_len);
138 filename[g_jackdbus_config_dir_len + conf_len] = 0;
140 jack_info("Saving settings to \"%s\" ...", filename);
142 fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
143 if (fd == -1)
145 jack_error("open() failed to open conf filename. error is %d (%s)", errno, strerror(errno));
146 goto exit_free_filename;
149 context.fd = fd;
151 if (!jack_controller_settings_write_string(fd, "<?xml version=\"1.0\"?>\n", dbus_call_context_ptr))
153 goto exit_close;
156 if (!jack_controller_settings_write_string(fd, "<!--\n", dbus_call_context_ptr))
158 goto exit_close;
161 if (!jack_controller_settings_write_string(fd, JACK_CONF_HEADER_TEXT, dbus_call_context_ptr))
163 goto exit_close;
166 if (!jack_controller_settings_write_string(fd, "-->\n", dbus_call_context_ptr))
168 goto exit_close;
171 if (!jack_controller_settings_write_string(fd, "<!-- ", dbus_call_context_ptr))
173 goto exit_close;
176 if (!jack_controller_settings_write_string(fd, timestamp_str, dbus_call_context_ptr))
178 goto exit_close;
181 if (!jack_controller_settings_write_string(fd, " -->\n", dbus_call_context_ptr))
183 goto exit_close;
186 if (!jack_controller_settings_write_string(fd, "<jack>\n", dbus_call_context_ptr))
188 goto exit_close;
191 /* engine */
193 if (!jack_controller_settings_write_string(fd, " <engine>\n", dbus_call_context_ptr))
195 goto exit_close;
198 context.indent = " ";
199 if (!jack_controller_settings_save_engine_options(&context, controller_ptr, dbus_call_context_ptr))
201 goto exit_close;
204 if (!jack_controller_settings_write_string(fd, " </engine>\n", dbus_call_context_ptr))
206 goto exit_close;
209 /* drivers */
211 if (!jack_controller_settings_write_string(fd, " <drivers>\n", dbus_call_context_ptr))
213 goto exit_close;
216 node_ptr = jackctl_server_get_drivers_list(controller_ptr->server);
218 while (node_ptr != NULL)
220 driver = (jackctl_driver_t *)node_ptr->data;
222 if (!jack_controller_settings_write_string(fd, " <driver name=\"", dbus_call_context_ptr))
224 goto exit_close;
227 if (!jack_controller_settings_write_string(fd, jackctl_driver_get_name(driver), dbus_call_context_ptr))
229 goto exit_close;
232 if (!jack_controller_settings_write_string(fd, "\">\n", dbus_call_context_ptr))
234 goto exit_close;
237 context.indent = " ";
239 if (!jack_controller_settings_save_driver_options(&context, driver, dbus_call_context_ptr))
241 goto exit_close;
244 if (!jack_controller_settings_write_string(fd, " </driver>\n", dbus_call_context_ptr))
246 goto exit_close;
249 node_ptr = jack_slist_next(node_ptr);
252 if (!jack_controller_settings_write_string(fd, " </drivers>\n", dbus_call_context_ptr))
254 goto exit_close;
257 /* internals */
259 if (!jack_controller_settings_write_string(fd, " <internals>\n", dbus_call_context_ptr))
261 goto exit_close;
264 node_ptr = jackctl_server_get_internals_list(controller_ptr->server);
266 while (node_ptr != NULL)
268 internal = (jackctl_internal_t *)node_ptr->data;
270 if (!jack_controller_settings_write_string(fd, " <internal name=\"", dbus_call_context_ptr))
272 goto exit_close;
275 if (!jack_controller_settings_write_string(fd, jackctl_internal_get_name(internal), dbus_call_context_ptr))
277 goto exit_close;
280 if (!jack_controller_settings_write_string(fd, "\">\n", dbus_call_context_ptr))
282 goto exit_close;
285 context.indent = " ";
287 if (!jack_controller_settings_save_internal_options(&context, internal, dbus_call_context_ptr))
289 goto exit_close;
292 if (!jack_controller_settings_write_string(fd, " </internal>\n", dbus_call_context_ptr))
294 goto exit_close;
297 node_ptr = jack_slist_next(node_ptr);
300 if (!jack_controller_settings_write_string(fd, " </internals>\n", dbus_call_context_ptr))
302 goto exit_close;
305 if (!jack_controller_settings_write_string(fd, "</jack>\n", dbus_call_context_ptr))
307 goto exit_close;
310 ret = true;
312 exit_close:
313 close(fd);
315 exit_free_filename:
316 free(filename);
318 exit:
319 return ret;
322 void
323 jack_controller_settings_save_auto(
324 struct jack_controller * controller_ptr)
326 jack_controller_settings_save(controller_ptr, NULL);