source: roaraudio/roard/clients.c @ 501:985357040570

Last change on this file since 501:985357040570 was 501:985357040570, checked in by phi, 16 years ago

ha! It's working: RoarAudio via DECnet! :), needs cleanup

File size: 8.6 KB
Line 
1//clients.c:
2
3#include "roard.h"
4
5int clients_init (void) {
6 int i;
7
8 for (i = 0; i < ROAR_CLIENTS_MAX; i++)
9  g_clients[i] = NULL;
10
11 return 0;
12}
13
14int clients_free (void) {
15 int i;
16
17 for (i = 0; i < ROAR_CLIENTS_MAX; i++)
18  if ( g_clients[i] )
19   clients_delete(i);
20
21 return 0;
22}
23
24int clients_new (void) {
25 int i;
26 int s;
27 struct roar_client * n;
28
29 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
30  if ( g_clients[i] == NULL ) {
31   n = malloc(sizeof(struct roar_client));
32   if ( n != NULL ) {
33    n->pid    = -1;
34    n->uid    = -1;
35    n->gid    = -1;
36    n->fh     = -1;
37
38    *n->name = 0;
39    *n->host = 0;
40
41    n->acl   = NULL;
42
43    n->execed = -1;
44    for (s = 0; s < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; s++)
45     n->streams[s] = -1;
46
47    g_clients[i] = n;
48
49    ROAR_DBG("clients_new(void) = %i", i);
50    return i;
51   } else {
52    ROAR_ERR("clients_new(void): Can not alloc memory for new client: %s", strerror(errno));
53    ROAR_ERR("clients_new(void) = -1");
54    return -1;
55   }
56  }
57 }
58
59 return -1;
60}
61
62int clients_delete (int id) {
63 int i;
64
65 if ( g_clients[id] == NULL )
66  return -1;
67
68 if (g_clients[id]->execed != -1) {
69//  return streams_delete(g_clients[id]->execed);
70  g_clients[id]->execed = -1;
71 }
72
73 for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) {
74  streams_delete(g_clients[id]->streams[i]);
75 }
76
77 if ( g_clients[id]->fh != -1 )
78  close(g_clients[id]->fh);
79
80 free(g_clients[id]);
81 g_clients[id] = NULL;
82
83 ROAR_DBG("clients_delete(id=%i) = 0", id);
84 return 0;
85}
86
87int clients_get       (int id, struct roar_client ** client) {
88 *client = g_clients[id];
89
90 if ( *client == NULL )
91  return -1;
92
93 return 0;
94}
95
96int clients_set_fh    (int id, int    fh) {
97#ifdef ROAR_HAVE_LIBDNET
98 struct sockaddr_dn sockaddr_d;
99 socklen_t len = sizeof(struct sockaddr_dn);
100#endif
101
102 if ( g_clients[id] == NULL )
103  return -1;
104
105 g_clients[id]->fh = fh;
106
107#ifdef ROAR_HAVE_LIBDNET
108 if ( getsockname(fh, (struct sockaddr *)&sockaddr_d, &len) != -1 ) {
109  if ( sockaddr_d.sdn_family == AF_DECnet )
110   roar_socket_nonblock(fh, ROAR_SOCKET_BLOCK);
111 }
112#endif
113
114 return 0;
115}
116
117int clients_set_pid   (int id, int    pid) {
118 if ( g_clients[id] == NULL )
119  return -1;
120
121 g_clients[id]->pid = pid;
122
123 return 0;
124}
125
126int clients_set_uid   (int id, int    uid) {
127 if ( g_clients[id] == NULL )
128  return -1;
129
130 g_clients[id]->uid = uid;
131
132 return 0;
133}
134
135int clients_set_gid   (int id, int    gid) {
136 if ( g_clients[id] == NULL )
137  return -1;
138
139 g_clients[id]->gid = gid;
140
141 return 0;
142}
143
144#define MAX_STREAMLESS 8
145
146int clients_check_all (void) {
147 struct timeval tv;
148 fd_set r, e;
149 int i, j;
150 int ret;
151 int fh;
152 int max_fh = -1;
153 int have = 0;
154 struct {
155  int id;
156  int fh;
157 } streamless[MAX_STREAMLESS];
158 int have_streamless = 0;
159 int have_stream;
160
161 FD_ZERO(&r);
162 FD_ZERO(&e);
163
164 tv.tv_sec  = 0;
165 tv.tv_usec = 1;
166
167 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
168  if ( g_clients[i] == NULL )
169   continue;
170
171  if ( (fh = g_clients[i]->fh) != -1 ) {
172   have++;
173
174   FD_SET(fh, &r);
175   FD_SET(fh, &e);
176
177   if ( fh > max_fh )
178    max_fh = fh;
179  }
180
181  have_stream = 0;
182
183  for (j = 0; j < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; j++) {
184   if ( (fh = streams_get_fh(g_clients[i]->streams[j])) != -1 ) {
185    FD_SET(fh, &r);
186
187    if ( fh > max_fh )
188     max_fh = fh;
189
190    have_stream = 1;
191   }
192   //printf("D: client=%i, stream=%i, fh=%i\n", i, j, fh);
193  }
194
195  if ( !have_stream && have_streamless < MAX_STREAMLESS ) {
196   streamless[have_streamless  ].id = i;
197   if ( (streamless[have_streamless++].fh = g_clients[i]->fh) == -1 )
198    have_streamless--;
199  }
200 }
201
202 if ( max_fh == -1 )
203  return 0;
204
205 if ( (ret = select(max_fh + 1, &r, NULL, &e, &tv)) < 1 ) {
206  return ret < 0 ? ret : have;
207 }
208
209 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
210  if ( g_clients[i] == NULL )
211   continue;
212
213  if ( (fh = g_clients[i]->fh) != -1 ) {
214   if ( FD_ISSET(fh, &r) ) {
215    if ( g_clients[i]->execed == -1 ) {
216     clients_check(i);
217/*
218    } else {
219     streams_check(g_clients[i]->execed);
220*/
221    }
222   }
223
224   if ( FD_ISSET(fh, &e) ) {
225    clients_delete(i);
226    continue;
227   }
228  }
229
230  if ( g_clients[i] == NULL )
231   continue;
232
233  for (j = 0; j < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; j++) {
234   //printf("D: client=%i, stream=%i, g_clients[i=%i] = %p\n", i, j, i, g_clients[i]);
235   if ( g_clients[i] == NULL ) // streams_check() bellow can delete our client (why?)
236    break;
237   if ( (fh = streams_get_fh(g_clients[i]->streams[j])) != -1 ) {
238    if ( FD_ISSET(fh, &r) ) {
239     streams_check(g_clients[i]->streams[j]);
240    }
241   }
242  }
243 }
244
245 if ( have_streamless ) {
246   FD_ZERO(&r);
247
248   tv.tv_sec  = 0;
249   tv.tv_usec = 1;
250
251   max_fh = -1;
252
253   for (i = 0; i < have_streamless; i++) {
254    fh = streamless[i].fh;
255
256    ROAR_DBG("clients_check_all(void): fh=%i", fh);
257    FD_SET(fh, &r);
258
259    if ( fh > max_fh )
260     max_fh = fh;
261   }
262
263   if ( (ret = select(max_fh + 1, &r, NULL, NULL, &tv)) < 0 ) {
264    return ret;
265   }
266
267   for (i = 0; i < have_streamless; i++) {
268    if ( FD_ISSET(streamless[i].fh, &r) ) {
269     clients_check(streamless[i].id);
270    }
271   }
272 }
273
274 ROAR_DBG("clients_check_all(void) = %i // have value", have);
275 return have;
276}
277
278int clients_check     (int id) {
279 struct roar_message    m;
280 struct roar_connection con;
281 char * data = NULL;
282 int oldcmd;
283 int r;
284 int rv = 0;
285
286 if ( g_clients[id] == NULL )
287  return -1;
288 if ( g_clients[id]->fh == -1 )
289  return -1;
290
291 con.fh = g_clients[id]->fh;
292
293 r = roar_recv_message(&con, &m, &data);
294
295 if ( r == -1 ) { // should we drop the client?
296  clients_delete(id);
297  return -1;
298 }
299
300 roar_debug_message_print(&m);
301
302 oldcmd = m.cmd;
303
304 if ( (r = command_exec(id, &m, data)) == -1 ) {
305  m.cmd     = ROAR_CMD_ERROR;
306  m.datalen = 0;
307  ROAR_DBG("clients_check(*): Exec of command faild!");
308 } else {
309  if ( m.cmd == oldcmd ) {
310   m.cmd     = ROAR_CMD_OK;
311   m.datalen = 0;
312  } else if ( m.cmd == ROAR_CMD_OK_STOP ) {
313   m.cmd     = ROAR_CMD_OK;
314   rv        = 1;
315  }
316 }
317
318 roar_send_message(&con, &m, NULL);
319
320 if ( data )
321  free(data);
322
323 ROAR_DBG("clients_check(id=%i) = 0", id);
324 return rv;
325}
326
327int clients_send_mon  (struct roar_audio_info * sa, uint32_t pos) {
328 int i;
329 int fh;
330
331 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
332  if ( g_clients[i] == NULL )
333   continue;
334
335  if ( (fh = g_clients[i]->fh) == -1 )
336   continue;
337
338  if ( g_clients[i]->execed == -1 ) {
339   // TODO: add some code to send a message to the client insetd of the raw data.
340  } else {
341//   streams_check(g_clients[i]->execed);
342   streams_send_mon(g_clients[i]->execed);
343//   if ( streams_send_mon(g_clients[i]->execed) == -1 )
344//    clients_delete(i); // delete client in case we could not write
345  }
346 }
347
348 return -1;
349}
350
351int clients_send_filter(struct roar_audio_info * sa, uint32_t pos) {
352 int i;
353 int fh;
354
355 for (i = 0; i < ROAR_CLIENTS_MAX; i++) {
356  if ( g_clients[i] == NULL )
357   continue;
358
359  if ( (fh = g_clients[i]->fh) == -1 )
360   continue;
361
362  if ( g_clients[i]->execed == -1 ) {
363   // TODO: add some code to send a message to the client insetd of the raw data.
364  } else {
365//   streams_check(g_clients[i]->execed);
366   streams_send_filter(g_clients[i]->execed);
367//   if ( streams_send_mon(g_clients[i]->execed) == -1 )
368//    clients_delete(i); // delete client in case we could not write
369  }
370 }
371
372 return -1;
373}
374
375int client_stream_exec   (int client, int stream) {
376 int i;
377
378 if ( g_clients[client] == NULL )
379  return -1;
380
381 for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) {
382  if ( g_clients[client]->streams[i] == stream ) {
383   g_clients[client]->execed = stream;
384   streams_set_fh(stream, g_clients[client]->fh);
385   streams_set_socktype(stream, ROAR_SOCKET_TYPE_GENSTR);
386   return 0;
387  }
388 }
389
390 return -1;
391}
392
393int client_stream_set_fh (int client, int stream, int fh) {
394 int i;
395
396 if ( g_clients[client] == NULL )
397  return -1;
398
399 for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) {
400  if ( g_clients[client]->streams[i] == stream ) {
401   streams_set_fh(stream, fh);
402   return 0;
403  }
404 }
405
406 return -1;
407}
408
409int client_stream_add    (int client, int stream) {
410 int i;
411
412 if ( g_clients[client] == NULL )
413  return -1;
414
415 for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) {
416  if ( g_clients[client]->streams[i] == -1 ) {
417   g_clients[client]->streams[i] = stream;
418   streams_set_client(stream, client);
419   return 0;
420  }
421 }
422
423 return -1;
424}
425
426int client_stream_delete (int client, int stream) {
427 int i;
428
429 if ( g_clients[client] == NULL )
430  return -1;
431
432 for (i = 0; i < ROAR_CLIENTS_MAX_STREAMS_PER_CLIENT; i++) {
433  if ( g_clients[client]->streams[i] == stream ) {
434   g_clients[client]->streams[i] = -1;
435
436   if ( stream == g_clients[client]->execed ) {
437    ROAR_DBG("client_stream_delete(client=%i, stream=%i): stream is execed one, deleting client!", client, stream);
438    clients_delete(client);
439   }
440
441   ROAR_DBG("client_stream_delete(client=%i, stream=%i) = 0", client, stream);
442   return 0;
443  }
444 }
445
446 ROAR_DBG("client_stream_delete(client=%i, stream=%i) = -1", client, stream);
447 return -1;
448}
449
450//ll
Note: See TracBrowser for help on using the repository browser.