chiark / gitweb /
Build fixes for uaudio ALSA/OSS backends.
[disorder] / server / state.c
CommitLineData
460b9539 1/*
2 * This file is part of DisOrder.
b50cfb8a 3 * Copyright (C) 2004, 2005, 2007-2009 Richard Kettlewell
460b9539 4 *
e7eb3a27 5 * This program is free software: you can redistribute it and/or modify
460b9539 6 * it under the terms of the GNU General Public License as published by
e7eb3a27 7 * the Free Software Foundation, either version 3 of the License, or
460b9539 8 * (at your option) any later version.
9 *
e7eb3a27
RK
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
460b9539 15 * You should have received a copy of the GNU General Public License
e7eb3a27 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
460b9539 17 */
132a5a4a
RK
18/** @file server/state.c
19 * @brief Global server state
20 */
05b75f8d 21#include "disorder-server.h"
460b9539 22
23static const char *current_unix;
24static int current_unix_fd;
25
26static struct addrinfo *current_listen_addrinfo;
27static int current_listen_fd;
28
b50cfb8a
RK
29/** @brief Current audio API */
30const struct uaudio *api;
31
460b9539 32void quit(ev_source *ev) {
4363757e 33 info("shutting down...");
460b9539 34 quitting(ev);
35 trackdb_close();
36 trackdb_deinit();
4363757e 37 info("exiting");
445a0f66 38 exit(0);
460b9539 39}
40
41static void reset_socket(ev_source *ev) {
42 const char *new_unix;
43 struct addrinfo *res;
44 struct sockaddr_un sun;
45 char *name;
46
47 static const struct addrinfo pref = {
66613034
RK
48 .ai_flags = AI_PASSIVE,
49 .ai_family = PF_INET,
50 .ai_socktype = SOCK_STREAM,
51 .ai_protocol = IPPROTO_TCP,
460b9539 52 };
53
54 /* unix first */
55 new_unix = config_get_file("socket");
56 if(!current_unix || strcmp(current_unix, new_unix)) {
57 /* either there was no socket, or there was but a different path */
58 if(current_unix) {
59 /* stop the old one and remove it from the filesystem */
60 server_stop(ev, current_unix_fd);
61 if(unlink(current_unix) < 0)
62 fatal(errno, "unlink %s", current_unix);
63 }
64 /* start the new one */
65 if(strlen(new_unix) >= sizeof sun.sun_path)
66 fatal(0, "socket path %s is too long", new_unix);
67 memset(&sun, 0, sizeof sun);
68 sun.sun_family = AF_UNIX;
69 strcpy(sun.sun_path, new_unix);
70 if(unlink(new_unix) < 0 && errno != ENOENT)
71 fatal(errno, "unlink %s", new_unix);
72 if((current_unix_fd = server_start(ev, PF_UNIX, sizeof sun,
73 (const struct sockaddr *)&sun,
74 new_unix)) >= 0) {
75 current_unix = new_unix;
76 if(chmod(new_unix, 0777) < 0)
77 fatal(errno, "error calling chmod %s", new_unix);
78 } else
79 current_unix = 0;
80 }
81
82 /* get the new listen config */
83 if(config->listen.n)
84 res = get_address(&config->listen, &pref, &name);
85 else
86 res = 0;
87
88 if((res && !current_listen_addrinfo)
89 || (current_listen_addrinfo
90 && (!res
91 || addrinfocmp(res, current_listen_addrinfo)))) {
92 /* something has to change */
93 if(current_listen_addrinfo) {
94 /* delete the old listener */
95 server_stop(ev, current_listen_fd);
96 freeaddrinfo(current_listen_addrinfo);
97 current_listen_addrinfo = 0;
98 }
99 if(res) {
100 /* start the new listener */
101 if((current_listen_fd = server_start(ev, res->ai_family, res->ai_addrlen,
102 res->ai_addr, name)) >= 0) {
103 current_listen_addrinfo = res;
104 res = 0;
105 }
106 }
107 }
108 /* if res is still set it needs freeing */
109 if(res)
110 freeaddrinfo(res);
111}
112
113int reconfigure(ev_source *ev, int reload) {
114 int need_another_rescan = 0;
115 int ret = 0;
116
117 D(("reconfigure(%d)", reload));
b50cfb8a
RK
118 if(api) {
119 if(api->close_mixer)
120 api->close_mixer();
121 api = NULL;
122 }
460b9539 123 if(reload) {
124 need_another_rescan = trackdb_rescan_cancel();
125 trackdb_close();
c00fce3a 126 if(config_read(1))
460b9539 127 ret = -1;
128 else {
129 /* Tell the speaker it needs to reload its config too. */
130 speaker_reload();
131 info("%s: installed new configuration", configfile);
132 }
d25c4615
RK
133 trackdb_open(TRACKDB_NO_UPGRADE);
134 } else
135 /* We only allow for upgrade at startup */
136 trackdb_open(TRACKDB_CAN_UPGRADE);
b50cfb8a
RK
137 api = uaudio_find(config->api);
138 if(api->open_mixer)
139 api->open_mixer();
460b9539 140 if(need_another_rescan)
dd9af5cb 141 trackdb_rescan(ev, 1/*check*/, 0, 0);
fdca70ee
RK
142 /* Arrange timeouts for schedule actions */
143 schedule_init(ev);
460b9539 144 if(!ret) {
145 queue_read();
146 recent_read();
147 reset_socket(ev);
148 }
149 return ret;
150}
151
152/*
153Local Variables:
154c-basic-offset:2
155comment-column:40
156End:
157*/