1 /*
2  *   LASH
3  *
4  *   Copyright (C) 2002 Robert Ham <rah@bash.sh>
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #define _GNU_SOURCE
22 
23 #include "config.h"
24 
25 #include <unistd.h>
26 #include <errno.h>
27 
28 #include <lash/lash.h>
29 #include <lash/loader.h>
30 #include <lash/internal_headers.h>
31 
32 #include "client_event.h"
33 
34 #ifndef MAXHOSTNAMELEN
35 #  define MAXHOSTNAMELEN  64
36 #endif
37 
38 void
server_lash_event_client_name(project_t * project,client_t * client,client_t * query_client,const char * name)39 server_lash_event_client_name(project_t * project, client_t * client,
40 							  client_t * query_client, const char *name)
41 {
42 	if (name)
43 		project_name_client(project, client, name);
44 	else {
45 		lash_event_t *event;
46 
47 		event = lash_event_new_with_type(LASH_Client_Name);
48 		lash_event_set_string(event, client->name);
49 		lash_event_set_project(event, project->name);
50 		lash_event_set_client_id(event, client->id);
51 
52 		conn_mgr_send_client_lash_event(project->server->conn_mgr,
53 										query_client->conn_id, event);
54 	}
55 }
56 
57 void
server_lash_event_jack_client_name(project_t * project,client_t * client,client_t * query_client,const char * name)58 server_lash_event_jack_client_name(project_t * project, client_t * client,
59 								   client_t * query_client, const char *name)
60 {
61 	if (name) {
62 		LASH_DEBUGARGS("setting jack client name for client '%s' to '%s'",
63 					   client_get_id_str(client), name);
64 
65 		if (client->jack_client_name) {
66 			fprintf(stderr,
67 					"%s client '%s' sent more than one jack client name\n",
68 					__FUNCTION__, client_get_id_str(client));
69 			return;
70 		}
71 
72 		client_set_jack_client_name(client, name);
73 
74 		LASH_DEBUGARGS
75 			("adding client '%s' to jack manager with client name '%s'",
76 			 client_get_id_str(client), name);
77 		jack_mgr_lock(project->server->jack_mgr);
78 		jack_mgr_add_client(project->server->jack_mgr, client->id, name,
79 							client->jack_patches);
80 		jack_mgr_unlock(project->server->jack_mgr);
81 		client->jack_patches = NULL;
82 		LASH_PRINT_DEBUG("added client");
83 
84 		server_notify_interfaces(project, client, LASH_Jack_Client_Name,
85 								 name);
86 	} else {
87 		lash_event_t *event;
88 
89 		event = lash_event_new_with_type(LASH_Jack_Client_Name);
90 		lash_event_set_string(event, client->jack_client_name);
91 		lash_event_set_project(event, project->name);
92 		lash_event_set_client_id(event, client->id);
93 		conn_mgr_send_client_lash_event(project->server->conn_mgr,
94 										query_client->conn_id, event);
95 	}
96 }
97 
98 void
server_lash_event_alsa_client_id(project_t * project,client_t * client,client_t * query_client,const char * string)99 server_lash_event_alsa_client_id(project_t * project, client_t * client,
100 								 client_t * query_client, const char *string)
101 {
102 	if (string) {
103 		LASH_DEBUGARGS("setting alsa client id for client '%s' to %d",
104 					   client_get_id_str(client), (unsigned char)string[0]);
105 
106 		if (client->alsa_client_id) {
107 			fprintf(stderr,
108 					"%s: client '%s' sent more than one alsa client id\n",
109 					__FUNCTION__, client_get_id_str(client));
110 			return;
111 		}
112 #ifdef HAVE_ALSA
113 		unsigned char alsa_id = (unsigned char)string[0];
114 		client_set_alsa_client_id(client, alsa_id);
115 
116 		alsa_mgr_lock(project->server->alsa_mgr);
117 		alsa_mgr_add_client(project->server->alsa_mgr, client->id, alsa_id,
118 							client->alsa_patches);
119 		alsa_mgr_unlock(project->server->alsa_mgr);
120 		client->alsa_patches = NULL;
121 
122 		server_notify_interfaces(project, client, LASH_Alsa_Client_ID,
123 								 string);
124 #endif
125 	} else {
126 		lash_event_t *event;
127 		char id[2];
128 
129 		event = lash_event_new_with_type(LASH_Alsa_Client_ID);
130 		lash_event_set_project(event, project->name);
131 		lash_event_set_client_id(event, client->id);
132 
133 		if (client->alsa_client_id) {
134 			id[0] = client->alsa_client_id;
135 			id[1] = '\0';
136 			lash_event_set_string(event, id);
137 		}
138 
139 		conn_mgr_send_client_lash_event(project->server->conn_mgr,
140 										query_client->conn_id, event);
141 	}
142 }
143 
144 void
server_lash_event_restore_data_set(project_t * project,client_t * client)145 server_lash_event_restore_data_set(project_t * project, client_t * client)
146 {
147 }
148 
149 void
server_lash_event_save_data_set(project_t * project,client_t * client)150 server_lash_event_save_data_set(project_t * project, client_t * client)
151 {
152 	project_data_set_complete(project, client);
153 }
154 
155 void
server_lash_event_save_file(project_t * project,client_t * client)156 server_lash_event_save_file(project_t * project, client_t * client)
157 {
158 	project_file_complete(project, client);
159 }
160 
161 void
server_lash_event_project_add(server_t * server,const char * dir)162 server_lash_event_project_add(server_t * server, const char *dir)
163 {
164 	project_t *project;
165 	client_t *client;
166 	lash_exec_params_t *exec_params;
167 	lash_list_t *node;
168 	char server_name[MAXHOSTNAMELEN];
169 	int err;
170 
171 	project = project_restore(server, dir);
172 	if (!project) {
173 		fprintf(stderr, "%s: could not restore project in dir '%s'\n",
174 				__FUNCTION__, dir);
175 		return;
176 	}
177 
178 	if (project_name_exists(server->projects, project->name)) {
179 		const char *name;
180 
181 		name = server_create_new_project_name(server);
182 		fprintf(stderr,
183 				"%s: changing project name for project in dir '%s' to '%s' to avoid clashing with existing project name '%s'\n",
184 				__FUNCTION__, dir, name, project->name);
185 		project_set_name(project, name);
186 	}
187 
188 #if 0
189 	err = gethostname(server_name, MAXHOSTNAMELEN);
190 	if (err == -1) {
191 		fprintf(stderr,
192 				"%s: could not get local host name, using 'localhost' instead: %s\n",
193 				__FUNCTION__, strerror(errno));
194 		strcpy(server_name, "localhost");
195 	}
196 #else
197 	strcpy(server_name, "localhost");
198 #endif
199 
200 	server->projects = lash_list_append(server->projects, project);
201 
202 	server_notify_interfaces(project, NULL, LASH_Project_Add, project->name);
203 	server_notify_interfaces(project, NULL, LASH_Project_Dir,
204 							 project->directory);
205 
206 	for (node = project->lost_clients; node; node = lash_list_next(node)) {
207 		client = (client_t *) node->data;
208 
209 		exec_params = lash_exec_params_new();
210 
211 		lash_exec_params_set_working_dir(exec_params, client->working_dir);
212 		lash_exec_params_set_server(exec_params, server_name);
213 		lash_exec_params_set_project(exec_params, project->name);
214 		lash_exec_params_set_args(exec_params, client->argc,
215 								  (const char *const *)client->argv);
216 		exec_params->flags = client->flags;
217 		uuid_copy(exec_params->id, client->id);
218 
219 		loader_load(server->loader, exec_params);
220 
221 		lash_exec_params_destroy(exec_params);
222 
223 		for (err = 0; err < client->argc; err++)
224 			free(client->argv[err]);
225 		free(client->argv);
226 		client->argv = NULL;
227 		client->argc = 0;
228 	}
229 
230 }
231 
232 void
server_lash_event_project_dir(project_t * project,client_t * client,const char * dir)233 server_lash_event_project_dir(project_t * project, client_t * client,
234 							  const char *dir)
235 {
236 	if (dir)
237 		project_move(project, dir);
238 	else {
239 		lash_event_t *event;
240 
241 		event = lash_event_new_with_type(LASH_Project_Dir);
242 		lash_event_set_string(event, project->directory);
243 		lash_event_set_project(event, project->name);
244 
245 		conn_mgr_send_client_lash_event(project->server->conn_mgr,
246 										client->conn_id, event);
247 	}
248 }
249 
250 void
server_lash_event_project_name(project_t * project,const char * name)251 server_lash_event_project_name(project_t * project, const char *name)
252 {
253 	server_notify_interfaces(project, NULL, LASH_Project_Name, name);
254 	project_set_name(project, name);
255 }
256 
257 void
server_lash_event_client_remove(project_t * project,client_t * client)258 server_lash_event_client_remove(project_t * project, client_t * client)
259 {
260 	project_remove_client(project, client);
261 }
262 
263 /* EOF */
264