chiark / gitweb /
*** empty log message ***
[sympathy.git] / apps / clients.c
1 /*
2  * clients.c:
3  *
4  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
5  * All rights reserved.
6  *
7  */
8
9 static char rcsid[] = "$Id$";
10
11 /*
12  * $Log$
13  * Revision 1.6  2008/02/15 03:32:07  james
14  * *** empty log message ***
15  *
16  * Revision 1.5  2008/02/14 10:34:47  james
17  * *** empty log message ***
18  *
19  * Revision 1.4  2008/02/14 10:34:30  james
20  * *** empty log message ***
21  *
22  * Revision 1.3  2008/02/14 02:46:44  james
23  * *** empty log message ***
24  *
25  * Revision 1.2  2008/02/14 00:57:58  james
26  * *** empty log message ***
27  *
28  * Revision 1.1  2008/02/13 18:05:06  james
29  * *** empty log message ***
30  *
31  */
32
33 #include <sympathy.h>
34 #include "clients.h"
35
36 static void
37 client_msg (IPC_Msg * m, Context * c)
38 {
39   switch (m->hdr.type)
40     {
41
42     case IPC_MSG_TYPE_NOOP:
43       break;
44     case IPC_MSG_TYPE_DEBUG:
45       fprintf (stderr, "%p [%d] %s\n", m, m->hdr.size, m->debug.msg);
46       break;
47     case IPC_MSG_TYPE_KEY:
48       vt102_send (c, m->key.key);
49       break;
50     case IPC_MSG_TYPE_SETBAUD:
51       tty_set_baud (c->t, m->setbaud.baud);
52       break;
53     case IPC_MSG_TYPE_SENDBREAK:
54       tty_send_break (c->t);
55       break;
56     case IPC_MSG_TYPE_SETFLOW:
57       tty_set_flow (c->t, m->setflow.flow);
58       break;
59     default:
60       fprintf (stderr, "Unhandeled message type %d\n", m->hdr.type);
61     }
62 }
63
64 void
65 client_free (Client * c)
66 {
67   if (c->s)
68     socket_free (c->s);
69
70   free (c);
71   fprintf (stderr, "Client at %p freed\n", c);
72 }
73
74 Client *
75 clients_new_client (Clients * cs, Socket * s, Context * ctx)
76 {
77   Client *c;
78
79   c = (Client *) malloc (sizeof (Client));
80
81   c->dead = 0;
82   c->s = s;
83   c->next = cs->head;
84
85   cs->head = c;
86   cs->n++;
87
88   fprintf (stderr, "Client at %p created\n", c);
89
90
91   if (ipc_msg_send_debug (s, "new_client"))
92     c->dead++;
93
94   return c;
95 }
96
97 void
98 clients_reap (Clients * cs)
99 {
100   Client **p, *c;
101
102
103   for (p = &cs->head; *p;)
104     {
105       Client *c = *p;
106
107       if (c->dead)
108         {
109           *p = c->next;
110           client_free (c);
111           cs->n--;
112         }
113       else
114         {
115           p = &(c->next);
116         }
117     }
118 }
119
120 Clients *
121 clients_new (void)
122 {
123   Clients *ret = (Clients *) malloc (sizeof (Clients));
124
125   ret->n = 0;
126   ret->head = NULL;
127
128   return ret;
129 }
130
131 void
132 clients_pre_select (Clients * cs, fd_set * rfds, fd_set * wfds)
133 {
134   Client *c;
135
136   for (c = cs->head; c; c = c->next)
137     {
138       socket_pre_select (c->s, rfds, wfds);
139     }
140 }
141
142 void
143 clients_post_select (Clients * cs, Context * ctx, fd_set * rfds,
144                      fd_set * wfds)
145 {
146   Client *c;
147   int deaded = 0;
148
149   for (c = cs->head; c; c = c->next)
150     {
151       if (socket_post_select (c->s, rfds, wfds))
152         {
153           c->dead++;
154           deaded++;
155         }
156
157       if (c->s->msg)
158         {
159           client_msg (c->s->msg, ctx);
160           socket_consume_msg (c->s);
161         }
162
163     }
164
165   if (deaded)
166     clients_reap (cs);
167 }
168
169
170 void
171 clients_shutdown (Clients * cs)
172 {
173   Client *c;
174
175   for (c = cs->head; c; c = c->next)
176     {
177       c->dead++;
178     }
179
180
181   clients_reap (cs);
182 }
183
184
185
186
187
188
189 int
190 send_status (Clients * cs, char *msg)
191 {
192   char mbuf[IPC_MAX_BUF + sizeof (IPC_Msg_status)];
193   IPC_Msg_status *m = (IPC_Msg_status *) mbuf;
194   int len;
195
196   Client *c;
197
198   if (!msg)
199     return;
200   len = strlen (msg) + 1;
201
202   if (!len)
203     return;
204   if (len > IPC_MAX_BUF)
205     len = IPC_MAX_BUF;
206
207   m->size = len + sizeof (IPC_Msg_status);
208   m->type = IPC_MSG_TYPE_STATUS;
209   strncpy (m->status, msg, IPC_MAX_BUF);
210   m->status[IPC_MAX_BUF - 1] = 0;
211
212   for (c = cs->head; c; c = c->next)
213     {
214       if (!c->dead)
215         if (ipc_msg_send (c->s, (IPC_Msg *) m))
216           c->dead++;
217     }
218
219   return len;
220 }
221
222
223 int
224 send_output (Clients * cs, void *buf, int len)
225 {
226   char mbuf[IPC_MAX_BUF + sizeof (IPC_Msg_term)];
227   IPC_Msg_term *m = (IPC_Msg_term *) mbuf;
228
229   Client *c;
230
231   if (!len)
232     return;
233   if (len > IPC_MAX_BUF)
234     len = IPC_MAX_BUF;
235
236   m->size = len + sizeof (IPC_Msg_term);
237   m->type = IPC_MSG_TYPE_TERM;
238   m->len = len;
239   memcpy (m->term, buf, len);
240
241   for (c = cs->head; c; c = c->next)
242     {
243       if (!c->dead)
244         if (ipc_msg_send (c->s, (IPC_Msg *) m))
245           c->dead++;
246     }
247
248
249   return len;
250 }
251
252 void
253 send_history (History * h, Client * c)
254 {
255   int rptr = h->wptr;
256
257   HISTORY_INC (h, rptr);
258
259   HISTORY_INC (h, rptr);
260   while (rptr != h->wptr)
261     {
262       History_ent *l = &h->lines[rptr];
263       if (l->valid)
264         {
265
266           if (ipc_msg_send_history (c->s, l))
267             c->dead++;
268
269         }
270       HISTORY_INC (h, rptr);
271     }
272 }
273
274 void
275 send_vt102 (VT102 * v, Client * c)
276 {
277   if (ipc_msg_send_vt102 (c->s, v))
278     c->dead++;
279
280 }