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