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